【问题标题】:Get CST current date at 00:00:00 time in java在java中的00:00:00时间获取CST当前日期
【发布时间】:2021-09-19 19:57:30
【问题描述】:

我需要在美国中部标准时间 00:00:00 采用以下格式的当前日期。

比如说当前日期是 2021 年 7 月 9 日,那么我需要该日期以及 00:00:00 时间。

预期输出:

Fri Jul 09 00:00:00 CST 2021

当前代码:

LocalDateTime date= LocalDateTime.now().with(LocalTime.MIN);
Date dayStart= Date.from(date.atZone(ZoneId.systemDefault()).toInstant());

CurrentCode 的输出: Fri Jul 09 00:00:00 UTC 2021

当前代码选择服务器时间/GMT,比 CST 早 5 小时。

示例: 09AM GMT is 14 CST/2PM CST

我已尝试将日历设置为 00:00:00,并将 setTimeZone 设置为 America/New_York。但是,当我将输出作为 calendar.getTime() 返回时,请给出其他时间而不是 CST 00:00:00。

试过了: @scheduled(zone="America/New_york" ) -- 不工作。

【问题讨论】:

  • 您将旧的/过时的 API 与现代的 API 混合在一起有什么特别的原因吗?您通过 java.time.LocalDateTime.now() 获取当前日期和时间(没有明确考虑时区),但使用旧的兼容性方法最终获得 java.util.Date
  • 它应该可以工作。我在本地机器上运行了这段代码,它运行良好。 ideone.com/3jVfUh。如果您在本地机器上运行,您可以通过更改您的机器时区来验证这一点。
  • 实际上它选择的服务器时间是 UTC/GMT。我需要将该 GMT 转换为 CST。当地时间它会工作。部署代码时它不起作用。
  • 在增强部分工作。这就是为什么有一个旧代码。存储库仅选择 00:00:00 作为 Date 对象。这就是日期结束的原因
  • America/New_york 不是 CST。 systemDefault 不是 CST。您在不使用区域/偏移信息的情况下组合了两个不同的时间 api。这里有很多东西要检查。您可以先将您的 ZoneId 设置为 America/Chicago(现在是 CDT),然后执行与您完全相同的操作吗?

标签: java date cron scheduler zone


【解决方案1】:

更改时区最简单的方法是使用 System.setProperty("user.timezone", "America/New_York");在 Java 注意:: America/New_York 不是 CST

import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneId;
import java.util.Date;

class DateAndTimeZoneFormatter {

    public static void main(String[] args) {
        
        System.setProperty("user.timezone", "America/New_York");

        LocalDateTime date = LocalDateTime.now().with(LocalTime.MIN);
        Date dayStart = Date.from(date.atZone(ZoneId.systemDefault()).toInstant());

        System.out.println(dayStart);

    }

}

【讨论】:

    【解决方案2】:

    您可以尝试使用带有特定ZoneIdZonedDateTime

    public static void main(String[] args) {
        // define the zone to be used
        ZoneId americaChicago = ZoneId.of("America/Chicago");
        // then take the date of today
        ZonedDateTime nowInChicago = ZonedDateTime.of(
                                        LocalDate.now(),  // today
                                        LocalTime.MIN,    // start of day
                                        americaChicago    // zone
                                     );
        // define an output format
        DateTimeFormatter dtf = new DateTimeFormatterBuilder()
                                        .appendPattern("EEE MMM dd HH:mm:ss")
                                        .appendLiteral(' ')
                                        .appendZoneText(TextStyle.SHORT)
                                        .appendLiteral(' ')
                                        .appendPattern("uuuu")
                                        .toFormatter(Locale.ENGLISH);
        // then print the formatted String representation
        System.out.println(nowInChicago.format(dtf));
    }
    

    这个输出

    Fri Jul 09 00:00:00 CDT 2021
    

    缺点:

    • 这与您的预期输出不完全匹配,因为 CST 没有被应用,因为它是夏令时。因此,CDT 将是输出。
    • 使用Date.from 这个ZonedDateTime.toInstant() 会影响值:

    应用这两行

    Date sameNowInChicago = Date.from(nowInChicago.toInstant());
    System.out.println(sameNowInChicago);
    

    会输出

    Fri Jul 09 07:00:00 CEST 2021
    

    在我的机器上,因为它配置为具有ZoneId.of("Europe/Berlin"),打印java.util.Date 时将考虑到这一点。
    CEST ⇒ 中欧夏令时间。

    【讨论】:

    • 是的,在转换为日期时,时间发生了变化。但它只会接受 Fri Jul 09 00:00:00 CDT 2021
    • 抱歉,@sangeetha,这不是很清楚。时间点不会因转换为日期而改变。当 deHaar 的 Date 与时间 07:00:00 一起打印时,这只是因为它们的时区。 Date 的值是正确的。 07:00:00 CEST00:00:00 CDT(北美中部夏令时间)的时间点相同。
    【解决方案3】:

    有两个很好的答案。我的建议只是在细节上有所不同(据某些人说,这就是魔鬼所在的地方)。

    首先,如果可以的话,你应该避免使用Date 类。您已经在使用现代 Java 日期和时间 API(LocalDateTimeLocalTimeZoneId)java.time。您将从 java.time 获得所需的所有功能。所以我假设您只是转换为Date,因为您需要一个Date 用于一些您现在无法升级到java.time 的遗留API。

        Instant startOfDay = ZonedDateTime.now(ZoneId.systemDefault())
                .truncatedTo(ChronoUnit.DAYS)
                .toInstant();
        Date oldfashionedDate = Date.from(startOfDay);
        
        System.out.println(oldfashionedDate);
    

    .truncatedTo(ChronoUnit.DAYS) 丢弃了ZonedDateTime 的时间部分,通常让我们在同一时区的同一天留下 00:00:00。

    编辑:

    我想要美国芝加哥时间 CDT

    在JVM的默认时区设置为America/Chicago的情况下运行上面的代码给出:

    2021 年 7 月 12 日星期一 00:00:00 CDT

    获得正确的Date 值和获得预期的打印输出是两件不同的事情,因为Date.toString() 选择JVM 的默认时区并使用它来呈现要返回的字符串。这种行为可能会让人感到意外。没有办法说服Date.toString()使用不同的时区,所以上面的输出只能通过设置默认时区来实现。

    原文:有很多时区被称为 CST,我无法确定您想要的是哪个时区(我相信 cmets 说 America/New_York 不是其中之一是正确的)。但是,我唯一可以说服老式Date 类缩写CST 的是中国标准时间。在亚洲/上海时区运行上述代码会得到以下输出:

    2021 年 7 月 10 日星期六 00:00:00 CST

    在我看来是对的。自从您提出问题以来,它已成为中国标准时区的 10 号星期六。

    任何时区都可以获取正确的Date 值,即该时区的一天的开始。您还希望在打印输出中使用 CST 的缩写。不适用于此的时区包括:

    • 澳大利亚/阿德莱德时区。输出为Sat Jul 10 00:00:00 ACST 2021。因此,即使澳大利亚中部标准时间有时缩写为 CST,Date 还是选择了 ACST。
    • 美国/哈瓦那。古巴在每年的这个时候使用古巴夏令时,因此输出 CDT。
    • 美国/温尼伯和美国/芝加哥。北美中部时间也使用夏令时,所以这里也输出 CDT。

    无论如何,你知道你想要哪个时区,所以我留给你选择。

    【讨论】:

    • 点赞.truncatedTo(ChronoUnit.DAYS)
    • 是的,@ArvindKumarAvinash,恕我直言,一个优点是我们只需要指定一次时区,因此不会出现错误时区规范不一致的风险(或默认时区在我们脚下被更改)当我们的代码在运行时)。
    • 我想要美国芝加哥时间 CDT @OleV.V.我检查了 Instant startOfDay = ZonedDateTime.now(ZoneId.of("America/New_York")) .truncatedTo(ChronoUnit.DAYS) .toInstant();日期 oldfashionedDate = Date.from(startOfDay); LOGGER.info("stackoverflow 日期检查-->"+oldfashionedDate);但没有给出预期的输出
    • 您需要设置 JVM 的默认时区才能获得该输出。请看我的编辑。 @sangeetha
    猜你喜欢
    • 2021-07-05
    • 1970-01-01
    • 2013-07-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-04
    • 1970-01-01
    相关资源
    最近更新 更多