【问题标题】:Java how to add time and dateJava如何添加时间和日期
【发布时间】:2016-11-29 19:48:35
【问题描述】:

使用 JDK 1.8 我有一天的时间(不是自 1970 年以来),我有一个日期,如何添加两者并创建一个日期时间。

谢谢 尝试过@Kikos soln 不会产生正确的结果: 在这种情况下,我的原始时间 930 小时以某种方式更改为 9:40,原始日期本身不应该有任何时间获取时间(??) - 所以加法数学失败。

   String testdate = "2015/10/25";
    Date date = new SimpleDateFormat("yyyy/mm/dd").parse(testdate);

    String timehrs= "930";
    long ltime = Long.parseLong("930");
    long hoursAsSeconds = (ltime / 100) * 60 * 60;
    long minsAsSeconds = (ltime % 100) * 60;
    long secondsOfDay = hoursAsSeconds + minsAsSeconds;

    System.out.println("testdate : "+ testdate +", timehrs: "+timehrs+" ,secondsOfDay: "+secondsOfDay); 
    System.out.println("Orig Date time formatted: "+ new SimpleDateFormat("yyyy-mm-dd hh:mm:ss").format(date));

    Date dt = new Date(date.getTime() + secondsOfDay*1000);

    System.out.println("New Date : "+ new SimpleDateFormat("yyyy-mm-dd hh:mm:ss").format(dt);  

testdate : 2015/10/25, timehrs: 930, secondsOfDay: 34200 原始日期时间格式:2015-10-25 12:10:00 新日期:2015-40-25 09:40:00
预计:2015-10-25 09:30:00

  1. 基于@Basil Bourque 的以下内容

    long nanosOfDay = TimeUnit.MILLISECONDS.toNanos( secondsOfDay*1000 );
    LocalTime lt = LocalTime.ofNanoOfDay( nanosOfDay ); ZoneId z = ZoneId.systemDefault(); ZonedDateTime zdt = ZonedDateTime.of( ld , lt , z );

    System.out.println("ZonedDateTime zdt: "+ zdt);

    ZonedDateTime zdt: 2015-10-25T09:30-07:00[America/Los_Angeles]

这是正确答案:2015-10-25T09:30

【问题讨论】:

  • 请提供代码示例。请输入示例输入和预期输出。
  • 不清楚你有什么。当您说“日期”时,您是指java.util.Date 吗?或者只是“约会”,如果那是什么? 一天的时间以毫秒为单位是什么意思?
  • Date 已经过时了,应该尽可能避免使用。使用 Java 8 类,例如 LocalDate、LocalTime、LocalDateTime、Instant、DateTimeFormatter、....
  • 我的日期只是一个 java.util.Date 从字符串创建(根据代码)。字符串没有时间组件,但是当我转换和格式化并看到它有时间时。我的时间也只是一天中的毫秒时间(不是自 1970 年以来)。

标签: datetime java-8


【解决方案1】:

问题很复杂

你说你有一天中的时间作为自午夜以来的毫秒数(显然)。然而930 表示时间00:00:00.930,而不是09:30:00,如您的示例数据所示。我将遵循您的文本而不是您的示例数据。

java.time

您正在使用麻烦的旧日期时间类,现在是遗留的,被 java.time 类所取代。忘记你听说过java.util.Date.Calendar

LocalDate

LocalDate 类表示没有时间和时区的仅日期值。

时区对于确定日期至关重要。对于任何给定的时刻,日期在全球范围内因区域而异。例如,Paris France 中午夜后几分钟是新的一天,而 Montréal Québec 中仍然是“昨天”。

ZoneId z = ZoneId.of( "America/Montreal" );
LocalDate today = LocalDate.now( z );

ISO 8601

java.time 类在解析/生成表示日期时间值的字符串时默认使用 ISO 8601 标准。要使您的输入字符串标准,请将这些斜杠字符替换为连字符。

String input = "2015/10/25".replace( "/" , "-" );
LocalDate ld = LocalDate.parse( input );

顺便说一句,分配给您的整个方案很笨拙、容易出错,而且不必要地复杂。要序列化系统间通信的日期时间值,请使用 ISO 8601 字符串格式。

LocalTime

你说你有一个毫秒数来表示一天中的时间作为从午夜开始的计数。

LocalTime 类提供了基于整秒持续时间和of nanoseconds 实例化的工厂方法。要获得纳秒,只需将毫秒乘以一千。更好的是,让TimeUnit 枚举来完成这项工作并使您的代码更具自我记录性。

long millisOfDay = Long.parseLong( "930" );
long nanosOfDay = TimeUnit.MILLISECONDS.toNanos( millisOfDay );  // Same effect as: ( millisOfDay * 1_000L )
LocalTime lt = LocalTime.ofNanoOfDay( nanosOfDay );

ZonedDateTime

现在将这两个Local… 对象与时区结合起来,以确定时间线上的一个点。这个日期和时间是指在魁北克蒙特利尔、法国巴黎、印度加尔各答还是新西兰奥克兰的某个时刻?

ZoneId z = ZoneId.of( "Pacific/Auckland" );
ZonedDateTime zdt = ZonedDateTime.of( ld , lt , z );

live code in IdeOne.com

ld.toString(): 2015-10-25

lt.toString(): 00:00:00.930

zdt.toString(): 2015-10-25T00:00:00.930+13:00[太平洋/奥克兰]

LocalDateTime

如果您的数据没有关于时区的信息,并且您不能安全地假定您的业务场景预期的时区,那么您没有比合并到 LocalDateTime 对象更好的选择。但请记住,这个值是不明确的。该值不是时间线上的一个点。该值表示时间线上的潜在点,只能通过分配给ZonedDateTimetime zone 或分配给OffsetDateTimeoffset-from-UTC 来确定。

LocalDateTime ldt = LocalDateTime.of( ld , lt );

关于java.time

java.time 框架内置于 Java 8 及更高版本中。这些类取代了麻烦的旧 legacy 日期时间类,例如 java.util.DateCalendarSimpleDateFormat

Joda-Time 项目现在位于maintenance mode,建议迁移到 java.time。

要了解更多信息,请参阅Oracle Tutorial。并在 Stack Overflow 上搜索许多示例和解释。规格为JSR 310

从哪里获得 java.time 类?

ThreeTen-Extra 项目通过附加类扩展了 java.time。该项目是未来可能添加到 java.time 的试验场。您可以在这里找到一些有用的类,例如IntervalYearWeekYearQuartermore

【讨论】:

  • 是的,这是对我有用的确切答案。 ZonedDateTime zdt = ZonedDateTime.of( ld , lt , z );
【解决方案2】:

类似:

Date dt = new Date(System.currentTimeMillis() + ms);
or
Date otherDate(....);
Date dt = new Date(otherDate.getTime() + ms);

【讨论】:

  • 我试过这个以某种方式失败 - 没有给出正确的结果 - 一些日期格式问题。我将在问题中详细说明。
猜你喜欢
  • 2016-11-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-04-10
相关资源
最近更新 更多