将UTC转换为EST不适用于Android上的夏令时

我一直在尝试将当地时间(EST)转换为UTC,反之亦然。因此,我呈现一个时间选择器,用户选择时间,然后将其转换为UTC并发送到服务器。这是代码:

        val cal = Calendar.getInstance()
        cal.set(Calendar.HOUR_OF_DAY,mHour) //mHour = 15
        cal.set(Calendar.MINUTE,mMinute)    //mMinute = 00
        cal.set(Calendar.SECOND,0)
        val formatter = SimpleDateFormat("HH:mm:ss")
        formatter.timeZone = TimeZone.getTimeZone("UTC")
        val cutOffTime = formatter.format(cal.time)  //this gives 19:00:00 which is correct

考虑到日光节约时间,cutoffTime的以上输出正确,因为15:00 EST是19:00 UTC。

现在,我从服务器获取相同的cutTime,并将其转换为本地(EST)并显示。这是代码:

        val cutOffTime = jsonObject.get("cutOffTime").getasString())  //value is 19:00:00
        var cutoffTime: Time? = null
        val format = SimpleDateFormat("hh:mm:ss")
        format.timeZone = TimeZone.getTimeZone("UTC")
        cutoffTime = Time(format.parse(cutOffTime).time)

        //cutoffTime has value 14:00 which is strange,it should be 15:00

因此,以上代码中的cutoffTime值为14:00,这很奇怪,应该为15:00。 请注意,此代码在2020年3月8日的日光节约时间之前有效。知道我在做什么错吗?

baobeisl521 回答:将UTC转换为EST不适用于Android上的夏令时

请不要使用过时且设计不良的Java api作为日期和时间。使用新的java.time API。它更加健壮,而且使用起来更方便。

以下是有关如何使用java.time编写代码的示例:

int mHour = 15;
int mMinute = 0;
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("HH:mm:ss");

ZonedDateTime toFormat = LocalDateTime
    .now() // Current date and time.
    .withHour(mHour).withMinute(mMinute).withSecond(0) // Change hour,minute and second like in your example.
    .truncatedTo(ChronoUnit.SECONDS) // Throw away milliseconds and nanoseconds.
    .atZone(ZoneOffset.UTC); // Say that the time is located at UTC+0.

String formatted = formatter
    .withZone(ZoneId.of("America/New_York")) // Create a new formatter that formats toFormat to the local time America/New_York.
    .format(toFormat);

System.out.println(formatted); // Gives 11:00:00 on my machine now. America/New_York is either UTC-5 or UTC-4.

ZonedDateTime parsed = LocalTime
    .parse(formatted,formatter) // Parse the String. The result is an instance of LocalTime.
    .atDate(LocalDate.now(ZoneId.of("America/New_York"))) // Add the date values which are those of the current local date at America/New_York.
    .atZone(ZoneId.of("America/New_York")); // Create a ZonedDateTime of the LocalDateTime to explicitly define the zone.

Instant pointInTimeA = parsed.toInstant();
Instant pointInTimeB = toFormat.toInstant();

System.out.println(pointInTimeA.equals(pointInTimeB)); // Gives true because both describe the same point in time as they should.

最大的好处是该api将为您处理与夏季和冬季有关的所有问题。已阅读here,以获取有关EST以及为什么不应该使用它的信息。

您面临的问题可能是由于您在一种格式化程序中使用了HH而在另一种格式化程序中使用了hh。这些不相同。已阅读here有关格式化和解析模式的信息。

,

我最终得到以下解决方案。我从服务器知道字符串的格式,因此我将其拆分。我不想使用新的时间API,因为它可以从API级别26开始使用。

                val cutOffString = jsonObject.get("cutOffTime").getAsString() //UTC date 19:00:00 from server

                val cal = Calendar.getInstance()
                cal.set(Calendar.HOUR_OF_DAY,cutOffString.split(":")[0].toInt())
                cal.set(Calendar.MINUTE,cutOffString.split(":")[1].toInt())
                cal.set(Calendar.SECOND,0)
                cal.timeZone = TimeZone.getTimeZone("UTC")

                val cutoffTime: Time = Time(cal.time.time) //15:00:00

本文链接:https://www.f2er.com/2669139.html

大家都在问