简体   繁体   English

如何从现有的java.util.Date对象中分别获取时间和日期部分

[英]How to get time and date parts separately from an existing java.util.Date object

I have been trying and trying but I'm pretty surprised as not to be able to find a solution for my simple problem. 我一直在尝试,但是对于无法为我的简单问题找到解决方案感到非常惊讶。

I have a date variable which has value like this: 我有一个日期变量,其值是这样的:

res0: java.util.Date = Mon Jul 15 07:50:59 AET 2019

now I want only the Date part not the time. 现在我只希望日期部分而不是时间。 the functions available in the Date for such are deprecated. 日期中可用的功能已弃用。 and all the solutions I found were using Calendar instance to get today's datetime and convert it into string using SimpleDateFormat. 我发现的所有解决方案都使用Calendar实例获取今天的日期时间,并使用SimpleDateFormat将其转换为字符串。

I don't want a string. 我不要字符串。 I want a Date without the time part and a time without the date part. 我想要一个没有时间部分的日期和一个没有日期部分的时间。

tl;dr tl; dr

myJavaUtilDate
.toInstant()
.atZone(
    ZoneId.of( "Australia/Sydney" )
) 
.toLocalDate() 

For time-of-day only, without date and without time zone: 仅限于一天中的时间,没有日期和时区:

.toLocalTime()

To generate a string, call: 要生成一个字符串,请调用:

.format(
    DateTimeFormatter
    .ofLocalizedDate( FormatSyle.MEDIUM )
    .withLocale( new Locale( "en" , "AU" ) )
)

Details 细节

Immediately convert your java.util.Date from its legacy class to the modern replacement, Instant . 立即将java.util.Date从其遗留类转换为现代替代品Instant

Instant instant = myJavaUtilDate.toInstant() ;

Both of those classes represent a moment as seen in UTC, that is, an offset of zero hours-minutes-seconds. 这两个类都代表UTC所示的时刻,即零时分分钟秒。 Adjust into a time zone by which you want to perceive the date. 调整到您想要感知日期的时区。

For any given moment the time-of-day and the date both vary by time zone around the globe. 对于任何给定时刻,一天中的时间和日期都会随世界各地的时区而变化。 Noon in Paris is not noon in Montréal. 巴黎的中午不是蒙特利尔的中午。 And a new day dawns earlier in the east than in the west. 东方比西方早到了新的一天。 You must get very clear on this to do proper date-time handling. 您必须对此非常清楚,以进行正确的日期时间处理。 One moment in nature can be viewed in many ways through human-created notions of time zones. 可以通过人类创建的时区概念以多种方式查看自然界中的时刻。

Specify a proper time zone name in the format of continent/region , such as America/Montreal , Africa/Casablanca , or Pacific/Auckland . continent/region的格式指定正确的时区名称 ,例如America/MontrealAfrica/CasablancaPacific/Auckland Never use the 3-4 letter pseudo-zones such as AET , EST , or IST as they are not true time zones, not standardized, and not even unique(!). 切勿使用3-4个字母的伪区域(例如AETESTIST因为它们不是真实的时区,不是标准化的,甚至不是唯一的(!)。

ZoneId z = ZoneId.of( "Australia/Sydney" ) ;

Apply to the Instant to get a ZonedDateTime . 应用于Instant以获得ZonedDateTime Both represent the same simultaneous moment, but are viewed with a different wall-clock time. 两者都表示相同的同时时刻,但以不同的挂钟时间查看。

ZonedDateTime zdt = instant.atZone( z ) ;

Extract the date-only portion. 提取仅日期部分。

LocalDate ld = zdt.toLocalDate() ;

Extract the time-of-day portion. 提取时间部分。

LocalTime lt = zdt.toLocalTime() ;

Put them back together again. 将它们重新放在一起。

ZonedDateTime zdt = ZonedDateTime.of( ld , lt , z ) ;

If you need a java.util.Date again to interoperate with old code not yet updated to java.time , convert. 如果需要再次使用java.util.Date与尚未更新为java.time的旧代码进行互操作,请进行转换。

Date d = Date.from( zdt.toInstant() ) ;

You can use LocalDate 您可以使用LocalDate

val input = new Date() // your date
val date = input.toInstant().atZone(ZoneId.of("Europe/Paris")).toLocalDate()

Here is a good answer: https://stackoverflow.com/a/21242111/2750966 这是一个很好的答案: https : //stackoverflow.com/a/21242111/2750966

You could use date formatter to turn it into String and parse it back to Date. 您可以使用日期格式化程序将其转换为String并将其解析回Date。

For example: 例如:

Date yourDate = ...;
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
Date date = dateFormat.parse(dateFormat.format(yourDate));

The new date object now only has the date part, with the time part being filled with zeroes. 现在,新的日期对象只有日期部分,时间部分用零填充。 For a numeric solution with the same result, check out this answer . 对于具有相同结果的数值解,请查看此答案 Alternatively, if you don't want the time part at all, this answer should suit you better. 另外,如果您根本不希望花费时间,则此答案应该更适合您。

We can do this using the date formatter, you can try the following code. 我们可以使用日期格式化程序来执行此操作,您可以尝试以下代码。

object DateFormatter extends App {
  val sdf = new SimpleDateFormat("EEEE MMMM dd, HH:mm:ss:SSS Z yyyy", Locale.ENGLISH)
  val date = new Date()
  val nowDate = sdf.format(date)
  println(nowDate)
  // It prints date in this format Monday July 22, 23:40:07:987 +0545 2019

  // Lets print the date in the format you have provided in your question
  val parsedDate = sdf.parse(nowDate)
  println(parsedDate)

  // Now, we have same date format as yours

  // Now we have to remove the time and keep the date part only, for this we can do this
  val newDateFormat = new SimpleDateFormat("yyyy-MM-dd")
  val dateOnly = newDateFormat.format(parsedDate)
  println(dateOnly)

  //Printing time only
  val timeFormatter = new SimpleDateFormat("HH:mm:ss")
  val timeOnly = timeFormatter.format(parsedDate)
  println(timeOnly)

  }

Output: 输出:

nowDate: Tuesday July 23, 07:08:05:857 +0545 2019
parsedDate: Tue Jul 23 07:08:05 NPT 2019
dateOnly: 2019-07-23
timeOnly: 07:08:05

Update 更新资料

val dateNotInString = newDateFormat.parse(dateOnly)
  println(dateNotInString)

Output of Update: 更新输出:

dateNotInString: Tue Jul 23 00:00:00 NPT 2019

Here, you can see that dateNotInString is a date object and it does not contain any time related info. 在这里,您可以看到dateNotInString是一个日期对象,并且不包含任何与时间相关的信息。 Similarly, time only info can be extracted. 同样,可以提取仅时间信息。

Second Update 第二次更新

We can't have a Date without the time part and without the date part using the SimpleDateFormat with type not String but we can convert it into LocaleDate and LocaleTime . 我们不能有一个日期没有时间部分,并且不使用的日期部分SimpleDateFormat类型not String ,但我们可以把它转换成LocaleDateLocaleTime

import java.time.Instant

  val instantTime = Instant.ofEpochMilli(parsedDate.getTime)

  import java.time.LocalDateTime
  import java.time.LocalTime
  import java.time.ZoneId

  val res = LocalDateTime.ofInstant(instantTime, ZoneId.systemDefault).toLocalTime
  println("localeTime " + res)

  val res1 = LocalDateTime.ofInstant(parsedDate.toInstant,ZoneId.systemDefault).toLocalDate
  println("localeDate " + res1)

Output of the second Update 第二次更新的输出

localeTime: 18:11:30.850
localeDate: 2019-07-23

It's type is LocaleTime and LocaleDate respectively now. 现在它的类型分别是LocaleTimeLocaleDate

    Date date = new Date(res0.getTime() - (res0.getTime() % 86400000));
    System.out.println(date);

Now you can use the date formatter as is with your res0 date and it will print the date only. 现在,您可以将日期格式化程序与res0日期一起使用,它将仅打印日期。 But what I tried to do is remove the time part basically 86400000 is the number of milliseconds per day and getTime return the number of milliseconds passed since January 1, 1970, 00:00:00 GMT. 但是我想做的是基本上除去时间部分86400000是每天的毫秒数,而getTime返回自格林尼治标准时间1970年1月1日00:00:00以来经过的毫秒数。 So basically this is equivalent to the date at time 00:00.00 of each day. 因此,基本上,这等效于每天00:00.00的日期。 I don't know if this is what you want because Date doesn't hold 2 separate things like date and time it just has a single long. 我不知道这是否是您想要的,因为Date不包含2个单独的东西,例如日期和时间,它只有一个long。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM