当前位置: 首页 > 知识库问答 >
问题:

如何解析Datetime并将其与相应的时区相关联

杨海
2023-03-14

我正在尝试读取格式为2019-12-23 13:35:00的字符串以创建一个DateTime对象并将其与我知道它对应的特定时区相关联(GMT-5)

我正在尝试这样做:

 val string1 = "2019-12-23 13:35:00"
    val sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
    sdf.setTimeZone(StaticDateTimeZone.forID("Etc/GMT-5").toTimeZone)
    val date = sdf.parse(string1)

输出不是我想要的,因为它没有假设日期时间不在GMT-5时区,而是在我的系统时区(GMT 0),因此将日期时间调整为GMT-5:< code > Mon Dec 23 08:35:00 GMT 2019

如何创建一个不更改输入,只将时区与之关联的datetime对象?

共有3个答案

慕皓君
2023-03-14
  • 我建议使用JodaTime。https://www.joda.org/joda-time/
  • JodaTime最好使用时区

例如,我编写了一个方法:

    public static Date getDateWithTimeZone(String dateString, String format, String timeZone) {
        DateFormat df = new SimpleDateFormat(format);
        Date dateObj = null;

        try {
            dateObj = df.parse(dateString);
            DateTime dateTime = new DateTime(dateObj);
            TimeZone zone = TimeZone.getTimeZone(timeZone);
            return dateTime.withZoneRetainFields(DateTimeZone.forTimeZone(zone))
                    .toDate();
        } catch (ParseException e) {
            logger.error("Error while converting string to date",e);
        }
        return null;
    }
  • 您可以根据需要更改方法/异常处理。希望这有帮助。
章青青
2023-03-14

好像你是用JodaTime然后转换成< code>java.util.Date。您可以直接使用Java 8中的< code>java.time包:

val string1 = "2019-12-23 13:35:00"
val formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")
val date = LocalDateTime.parse(string1, formatter)
date.atZone(ZoneId.of("Etc/GMT-5"))

这给了:

date: java.time.LocalDateTime = 2019-12-23T13:35
res0: java.time.ZonedDateTime = 2019-12-23T13:35+05:00[Etc/GMT-5]

LocalDateTime生成一个没有附加任何时区的日期。最后一行有效地从上一个日期创建了一个新的ZonedDateTime,并在上面添加了给定的时区。如果您需要返回java.util.Date,请参阅此答案。

阙佐
2023-03-14

(使用Java语法而不是Scala)

我知道它对应的特定时区(GMT-5)

< code>GMT-5不是一个时区,它只是一个时差。时区的名称采用< code >洲/地区格式,例如< code >非洲/突尼斯。时区是一个地区使用的偏移量的变化历史。

您无法根据偏移量可靠地确定时区。许多时区在特定时刻可能共享相同的偏移,但在其他时刻可能不同。所以你只能胡乱猜测。仅当您确定特定时区时,才应用时区。

相反,使用偏移本身来确定一个没有区域的时刻。这是一个单行解决方案

LocalDateTime                                     // Represent a date with time-of-day but lacking the context of an offset-from-UTC or a time zone.
.parse(                                           // When parsing, no need to specify a formatting pattern when the input complies with the ISO 8601 standard.        
    "2019-12-23 13:35:00".replace( " " , "T" )    // Comply with ISO 8601 standard formatting, replacing SPACE in the middle with an uppercase `T`. 
)                                                 // Returns a `LocalDateTime` object.
.atOffset(                                        // Determine a moment by placing the date and time-of-day of a `LocalDateTime` into the context of an offset-from-UTC.
    ZoneOffset.ofHours( -5 )                      // Represent an offset-from-UTC with `ZoneOffset`, merely a number of hours-minutes-seconds ahead or behind the prime meridian. 
)                                                 // Returns a `OffsetDateTime` object.
.toString()                                       // Generate text in standard ISO 8601 format.

实时运行代码。

2019-12-23T13:35-05:00

您的输入字符串几乎是ISO 8601标准格式。为了符合要求,请用< code>T替换中间的空格。

String input = "2019-12-23 13:35:00".replace( " " , "T" ) ;

如果您的输入缺少时区或UTC偏移量,则解析为< code>LocalDateTime。

LocalDateTime ldt = LocalDateTime.parse( input ) ;

请注意,LocalDateTime不是一个时刻,不是时间线上的一个点。在您的大约下午1:30的示例中,我们不知道这意味着日本东京的下午1:30还是美国俄亥俄州托莱多的下午1:30,这两个非常不同的时刻相隔数小时。

您声称可以肯定地知道,这个日期和时间是通过比UTC晚五小时(通常在本初子午线以西)的偏移量来观察的。

ZoneOffset offset = ZoneOffset.ofHours( -5 ) ;  // Five hours before UTC.

因此,让我们应用该 ZoneOffset 来获取 OffsetDateTime

OffsetDateTime odt = ldt.atOffset( offset ) ;

请参阅此代码在 IdeOne.com 实时运行。

odt.toString(): 2019-12-23T13:35-05:00

时区总是比仅仅从UTC偏移更可取。偏移是小时——分钟——秒的数字,仅此而已。时区要多得多。时区是特定地区人民使用的偏移过去、现在和未来变化的历史。

但不要猜测时区。仅当您知道您的LocalDateTime对象最初是为该区域设计的时,才应用该区域。

以大陆/地区格式指定正确的时区名称,例如美洲/蒙特利尔、非洲/卡萨布兰卡太平洋/奥克兰切勿使用 2-4 个字母的缩写,例如 ESTIST,因为它们不是真正的时区,不是标准化的,甚至不是唯一的(!)。

ZoneId z = ZoneId.of( "America/Panama" ) ;
ZonedDateTime zdt = ldt.atZone( z ) ;

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

要了解更多信息,请参阅Oracle教程。并搜索Stack Overflow以获取许多示例和解释。规范是JSR 310。

Joda-Time 项目现在处于维护模式,建议迁移到 java.time 类。

您可以直接与数据库交换java.time对象。使用符合JDBC 4.2或更高版本的JDBC驱动程序。不需要字符串,不需要java.sql.*类。

从哪里获得java.time类?

  • JavaSE 8、JavaSE 9、JavaSE 10、JavaSE 11及更高版本-带有捆绑实现的标准JavaAPI的一部分。
    • Java9添加了一些小功能和修复。
    • 大部分java.time功能向后移植到Java6
    • java.time 类的 Android 捆绑包实现的更高版本。
    • 对于早期的Android (

    ThreeTen-Extra项目用额外的类扩展了java.time。这个项目是java.time未来可能增加的内容的试验场。您可能会在这里找到一些有用的类,如< code>Interval 、< code>YearWeek 、< code>YearQuarter等等。

 类似资料:
  • 我试图更深入地理解java.util.Collection和java.util.Map,但我对HashSet的功能有些怀疑: 所以,我的问题是:如果一个HashSet总是有一个Hashtable在后台工作,那么每次我们使用HashSet.add()方法向HashSet添加一个新元素时,HashSet都应该将它添加到它的内部Hashtable中。但是,哈希表要求一个值和一个键,那么它使用什么键呢?它

  • 本文向大家介绍协方差与相关性的区别?相关面试题,主要包含被问及协方差与相关性的区别?时的应答技巧和注意事项,需要的朋友参考一下 相关性是协方差的标准化格式,协方差本身很难做比较,例如,如果我们计算工资和年龄的协方差,因为这两个变量有不同的度量,所以我们会得到不能做比较的不同的协方差,为了解决这个问题,我们计算相关性来得到一个介于-1和1之间的值,就可以忽略它们各自不同的度量

  • 问题内容: 这是我的CSV 第一行是列的名称。我试过fgetcsv(),但所有要做的就是显示所有行。而不是我想要的。我该怎么做? 因此,如果我将数据最后放入数组中,我将能够打印出表格格式的数据,就像excel中所示。 谢谢 这是我的样本: 这是我的输出:(我将$ row放到pre中,以便可以显示它) 问题答案: 要一次阅读所有内容,可以使用: 要将所有行变成一个很好的关联数组,可以应用:

  • 我的Android项目中的数据类模型有一个变量lets,称之为value。 数据类Person(名称:String=“”,值:Int=0){} 我希望Int类型的变量值随时间减少。假设它每天减少1。所以如果今天是10,明天是9,后天是8等等,即使我的应用程序“死了”/没有打开。我该如何去实现这一点呢?

  • 问题内容: 我正在使用Node.js和Socket.io进行复杂的游戏,需要将socket.io对象存储在内存中,还需要为套接字对象分配属性(例如,名称,来​​自套接字的某些操作的计数器等) 在下面的代码中,我展示了一个我要实现的示例。我将所有套接字存储在一个数组中,并且还有另一个数组用于存储套接字的name属性。在任何时候,如果我收到名称的请求,都可以从内存中的数组中选择名称。 但是现在我的用户