如何将 TypeScript 日期转换为 Java 日期

How to convert TypeScript Date to a Java Date

我有一个 Spring 应用程序,我从 angular 客户端收到一个字符串形式的日期,我如何将这个日期转换为 Java 日期,以下是 TypeScript日期格式:

TypeScript 日期格式: Mon Jan 04 2021 00:00:00 GMT+0100 (Central European Standard Time)

Java 日期格式: Mon Jan 04 00:00:00 CET 2021

Mon Jan 04 2021 00:00:00 GMT+0100 (Central European Standard Time)

这是一个不明确的时间戳。政治实体和整个世界可以自由地重新定义 CEST 的含义,此时 GMT+0100 意味着一回事,而 CST 意味着另一回事。此外,CEST 对在此日期不同于 GMT+0100 的任何 'math' 有影响。

例如,如果我想知道从那个日期起 6 个月的日期,那么如果 CST 领先,您需要:

Thu Jul 04 2021 00:00:00 GMT+0200 (Central European Daylight Time)

或者您可能想要那个时间但提前一个小时 - 另一个悬而未决的问题,这个想法中固有的问题没有明确的答案 'add 6 months to this timestamp',因此您必须指定它,否则你得到系统的一些随机猜测,你几乎不希望你的计算机/编程语言猜测这样一个 50/50 的概念。

如果 GMT+0100 领先,您将得到:

Thu Jul 04 2021 00:00:00 GMT+0100 (Central European Standard Time)

完全奇怪 在整个星球上,这个时间戳有意义的打印位置为零:没有人 在 CEST 上7 月 4 日,任何地方。这是一个 'real' 的时间戳,但实际上只有 0 人使用。

因此,在继续之前,首先您需要问问自己,您希望在转换时保留您所拥有的哪些点点滴滴。请注意,有 3 种不同的时间概念:

  • 'solarflares' 时间:通常以毫秒为单位来衡量。这没有时区等人类概念。记录事件发生或将要发生的确切时间,如果该事件不是人类约定的(即预计太阳耀斑发生或确实发生的时间,因此得名 'solarflares' 时间)。在 java 中,最好的代表是 java.time.Instant

  • 'appointment'时间:通常用一大袋数字来衡量:年、月、日、时、分、秒, 一个时区。不是那些 GMT+0100 无用区域之一,而是像 Europe/Amsterdam 这样的区域。 Central European Standard Time 之类的东西有点常见,但也是一个非常糟糕的主意。这些名称没有明确的含义,像 Europe/Amsterdam 这样的名称很可能总是具有明确的含义,这是一个适当的区域。这个想法是:假设您预约了下个月在阿姆斯特丹的牙医。这看起来确实像是一场 solarflares 交易,但事实并非如此:如果荷兰决定加入不同的时区,那么在你的约会发生之前的绝对秒数也会随之改变。而太阳耀斑不会提前一个小时发生,只是因为某个政治实体下令如此。

  • 'alarm'时间:类似预约时间,但没有时区信息为基础。如果您将闹钟设置为早上 8 点叫醒您,然后您跳上飞机向西飞了一堆,您希望闹钟仍然在当地时间早上 8 点响起:闹钟响起前的秒数当您跨区域移动时,关闭应该会改变。

那么,您的时间价值打算代表什么?

如果'solarflares'时间。

然后工作就是首先将它转换成一个 java.time.Instant 对象,然后从那里获取它。例如,通过 .atZone() 转换回约会时间,然后使用 java.time.format.DateTimeFormatter 将其打印成看起来像这样的字符串。想象一下输入是新加坡时间,然后使用此策略输出是 CET 中的 still。另外,我觉得你显示字符串不是因为你需要像那样格式化字符串,而是因为你错误地认为 java 以这种字符串格式存储时间。它没有; java 将约会时间存储为具有年、月、日等字段的对象。将其打印到字符串中是分离出来的,并由格式化程序控制。你可以做一个格式化程序来打印它。

可以根据 GMT+0100 将其解析为 j.t.Instant 值,您可以忽略 CEST 尾随文本。

如果'appointments'次。

然后你需要把它解析出来,这是非常重要的; GMT+0100 不是你想要的,它是一个合法区域,但不是一个有用的区域(CEST 区域中没有国家使用 GMT+0100。地球上有些地方全年都是 GMT+0100。它们不是,但是,中欧附近的任何地方)。因此,除了 GMT+0100,包括 CEST,相关的位是所有的,这不是标准的日期格式,据我所知,'Central European Standard Time' 不是 java.time 可以识别的东西。您将需要 table 打字稿此时可以生成的所有可能字符串。

如果'alarm time'

那你可以在最后一个:00之后停止解析,剩下的扔掉。使用正则表达式将其剥离,然后使用 LocalDateTime.of(stringValue, formatter) 方法解析为 LocalDateTime。很简单。

忠告

尝试让您的 TypeScript 以其他方式打印这些内容。一种很好的方法是将太阳耀斑时间与明确的区域结合起来(如 Europe/Amsterdam,而不是 Central European Standard Time)。这更容易重新解析为 3 种不同的时间概念方式中的任何一种。

java.time

how can i convert this date to a Java Date, following is the TypeScript Date format :

TypeScript Date Format : Mon Jan 04 2021 00:00:00 GMT+0100 (Central European Standard Time)

java.time 为您提供了 DateTimeFormatterBuilder,您可以使用它为 parsing/formatting 定义复杂的格式,如下所示:

import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
import java.time.format.TextStyle;
import java.util.HashSet;
import java.util.Locale;

public class Main {
    public static void main(String[] args) {
        String strDateTime = "Mon Jan 04 2021 00:00:00 GMT+0100 (Central European Standard Time)";
        DateTimeFormatter dtf = new DateTimeFormatterBuilder()
                                    .parseCaseInsensitive()
                                    .appendPattern("EEE MMM dd uuuu HH:mm:ss")
                                    .appendLiteral(" ")
                                    .appendZoneRegionId()
                                    .appendOffset("+HHmm", "Z")
                                    .appendLiteral(" (")
                                    .appendZoneText(TextStyle.FULL)
                                    .appendLiteral(")")
                                    .toFormatter(Locale.ENGLISH);
        ZonedDateTime zdt = ZonedDateTime.parse(strDateTime, dtf);
        System.out.println(zdt);
    }
}

输出:

2021-01-04T00:00+01:00[Europe/Paris]

Java Date Format : Mon Jan 04 00:00:00 CET 2021

日期时间对象应该存储有关日期、时间、时区等的信息,而不是格式。您可以使用日期时间格式 String 将日期时间对象格式化为您选择的模式 API.

  • 现代日期时间类型的日期时间格式API在包中,java.time.format例如java.time.format.DateTimeFormatterjava.time.format.DateTimeFormatterBuilder
  • 旧日期时间类型的日期时间格式 API 在包中,java.text 例如java.text.SimpleDateFormatjava.text.DateFormat

下面给出了如何将 zdt(上面获得的)格式化为自定义格式:

DateTimeFormatter dtfOutput = DateTimeFormatter.ofPattern("EEE MMM dd HH:mm:ss z uuuu", Locale.ENGLISH);
String strDateTimeFormatted = zdt.format(dtfOutput);
System.out.println(strDateTimeFormatted);

输出:

Mon Jan 04 00:00:00 CET 2021

Trail: Date Time.

了解现代日期时间 API

如果你想将zdt(上面得到的)转换成java.util.Date,你可以如下所示进行:

Date date = Date.from(zdt.toInstant());
System.out.println(date);

关于遗留日期时间的注释API:

java.util.Date 对象不像 modern date-time types 那样是真正的日期时间对象;相反,它表示距 Epoch of January 1, 1970 的毫秒数。当您打印 java.util.Date 的对象时,它的 toString 方法 returns 根据此毫秒值计算的日期时间。由于 java.util.Date 没有时区信息,它会应用 JVM 的时区并显示相同的时区。如果需要在不同时区打印日期时间,则需要将时区设置为 SimpleDateFomrat 并从中获取格式化字符串。 3. java.util 的日期时间 API 及其格式 API、SimpleDateFormat 已过时且容易出错。建议完全停止使用它们并切换到 modern date-time API.

  • 出于任何原因,如果您必须坚持使用 Java 6 或 Java 7,您可以使用 ThreeTen-Backport,它向后移植了大部分 java.time Java 6 和 7 的功能。
  • 如果您正在为 Android 项目工作,并且您的 Android API 级别仍然不符合 Java-8,请检查 Java 8+ APIs available through desugaring and

您可以使用纪元时间在客户端和服务器之间共享时间,这是一种简单的方法。

Typescript 纪元时间管理

const epoch = new Date().getTime();
console.log(epoch);

const date = new Date(epoch);
console.log(date);

结果:

1609801111672

Date Mon Jan 04 2021 22:58:31 GMT+0000 (Western European Standard Time)

Java 使用 java.util.Date

的纪元时间管理
long epoch = new Date().getTime();  
log.debug( "Epoch: {}", epoch );
        
Date date = new Date(epoch);    
log.debug( "Date: {}", date );

结果

Epoch: 1609801111672

Date: 2021-01-04T22:58:31.672Z