【问题标题】:How can I represent time of the day in Java?如何在 Java 中表示一天中的时间?
【发布时间】:2014-01-23 20:32:00
【问题描述】:

我希望能够创建各种日历,其中每一天都由时间段组成。用 Java 表示此设置的最佳方式是什么?我正在解析信息,并将其作为 10:00 和一个 int 3 得到,其中 int 表示事件将花费的时间。

我希望能够轻松添加事件,它们永远不会真正被删除,但它们会经常被查找。

我查看了 Java.text.DateFormat,希望它能满足我的需求,但它似乎主要用于打印输出。

【问题讨论】:

  • 我可能会使用Joda-Time
  • 所以,创建一个CalendarEvent 类,其中包含一个startTime 和一个eventLength。我同意其他人的观点,Joda-Time 将成为存储您的日期/时间/等的有用库。并对它们进行计算。
  • 你可以使用 SimpleDateFormat 来表示时间值,记住,Date/DateTime 是脱离格式的,所以它不会带有 for at。您可以使用 Calendar 根据基准日期计算未来时间,但我个人会使用 Joda-Time,因为它通常简化了对日期/时间值执行计算的整个过程。请记住,您需要的不仅仅是时间,因为事件可能会超出当天的范围;)
  • @user1198778 这个问题的标题很差,具有误导性。

标签: java date calendar


【解决方案1】:

使用Joda-Time(或等待Java 8 实现它的继任者)。 该库还包含强大的解析选项和方便的操作选项。如果您收到一个包含事件所需时间的 int,您可以使用它来获取结束时间。

int hours = (parsed from input);
DateTimeFormatter dtf = DateTimeFormat.forPattern("HH:mm");     
LocalTime startTime = dtf.parseLocalTime(stringWithTimeFromUser);
LocalTime endTime = startTime.plusHours(hours);

如果您需要将其转换为日期时间,您也可以组合这些类。 IE。如果您有日期时间并且只想将时间更改为用户提供的时间,您会:

DateTime dateTime = getItFromSomewhere();
DateTime dateTimeWithNewTime = dateTime.withFields(localTime);

通常你也会从用户那里得到日期;)

图书馆有大量的文档,看那里。

【讨论】:

  • 我很好奇如果您添加足够的时间将 LocalTime 推送到当天(即设置为晚上 10 点并添加 4 小时)会发生什么情况,您是否能够检测到此更改(没有必须恢复到之前/之后的比较)?
  • @MadProgrammer 将 4 小时加到晚上 10 点会发生什么?时钟上的指针继续围绕表盘旋转。 System.out.println( new LocalTime( 22, 0 ).plusHours( 4 ) ); 产生 02:00:00.000。没有什么可以真正检测到,否则您将使用 DateTime。
  • @BasilBourque 哈哈 ;)。我很好奇的是,如果没有Date 组件,您如何检测到这一点,例如,如果我想计算两者之间的“拆分”(即在一列上渲染 2200-2400,在下一列渲染 0000-0200 ),是否有可能知道我使用LocalTime 跳过了日期边界?这不是批评,只是好奇。我之前用过LocalTime 来计算时间差,太棒了
  • 查看了课堂文档,除了 MIDNIGHT 的常量之外,没有看到任何相关的内容。我的想法是……你所说的“分裂”实际上是日期的含义。如果加法的结果是一个月中的不同日期,那么您就知道您已经翻车了。我认为LocalTime 是那些在表盘上带有大而粗的分针和时针的玩具时钟之一,它意味着可以手动移动,让小孩学习看时间。我的意思是LocalTime 是一个假装的一天中无休止地转来转去的时间,没有任何意义。如果您关心滚动,那么您关心日期。
  • @MadProgrammer 假设您添加的时间不超过 24 小时(您可以轻松检查),您可以检查 newLocalTime.isBefore(previousLocalTime) ;) 因为您必须检查您是否添加的时间不超过24 小时,您还可以获得距离午夜还剩多少时间并对此进行验证:Minutes.minutesBetween(previousLocalTime, LocalTime.MIDNIGHT).getMinutes() 我希望这里的每个人都意识到这一切都没有意义 - 如果您需要检查这一点,您需要一个 DateTime :)
【解决方案2】:

使用 Joda-Time 表示实际时间。然后我会使用 PrimeFaces Schedule 组件 (http://www.primefaces.org/showcase/ui/scheduleHome.jsf) 进行显示。

这意味着学习 JSF 和 JPA 库。

【讨论】:

  • Nitpick:我认为没有足够的上下文来了解 OP 打算如何向用户表示这个概念,但这只是我 ;)
  • 他说“创建一个各种各样的日历,其中每一天都由时间段组成”。
  • 是的,但这并不规定框架,例如可以使用 Swing 或 JavaFX 来做到这一点
【解决方案3】:

拒绝旧的捆绑类

避免捆绑 java.util.Date、java.util.Calendar 和 java.text.DateFormat/SimpleDateFormat 类。它们是出了名的麻烦。

是的,Joda-Time

是的,Joda-Time 2.3 有满足您需求的课程。

DateTime 代表一个时刻。请参阅 PeriodDurationInterval 类,它们都与时间跨度相关。

日期时间类

DateTime 代表一个时刻以及一个时区。与 似乎 有一个时区但实际上没有的 java.util.Date 不同,DateTime 确实分配了一个时区。几乎总是最好指定时区,否则你会得到 JVM 的默认时区。

期间类

ISO 8601 标准定义了一种表示时间跨度的文本方式,称为Duration。使用这种格式:PnYnMnDTnHnMnS。为了更加灵活,您可以存储PT3H,而不是存储三个小时的整数,其中“P”表示周期,“T”表示时间部分,“3H”表示三个小时。在 Joda-Time 中,Period 类将该字符串作为构造函数,并在调用 toString 时将其输出。因此,制作日历的一种方法是存储 DateTime(开始)和 ISO 字符串“Duration”。

Period period = new Period( "PT3H" );

持续时间类

另一种常用方法是以毫秒为单位存储持续时间。这基本上是 Joda-Time 中的 Duration 字段所做的,包含毫秒计数。

间隔类

在 Joda-Time 中的 Interval 中表示具有特定日期时间开始和日期时间结束的跨度。您可能不想存储它,但实例化此类对象可能有其他用途。此类提供了方便的方法,例如“重叠”和containsNow。如果“containsNow”返回 true,您就知道该事件正在发生。

DateTimeZone timeZone = DateTimeZone.forID( "Europe/Paris" );
DateTime startDateTime = new DateTime( 2014, 1, 23, 14, 0, 0, timeZone );
Interval interval = new Interval( startDateTime, period );

转储到控制台...

System.out.println( "interval: " + interval );

运行时……

interval: 2014-01-23T14:00:00.000+01:00/2014-01-23T17:00:00.000+01:00

是 java.time.*

Java 8 带来了由JSR 310 定义的类的新java.time.* package。这些课程的灵感来自 Joda-Time,但经过完全重新设计。

您现在可以使用 Joda-Time 并继续使用 Java 8,因为该项目将继续得到积极维护。稍后您将学习过渡到 java.time 包。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-05
    相关资源
    最近更新 更多