Java中ZonedDateTime转换为Epoch秒数而不转换为本地时间。

huangapple go评论69阅读模式
英文:

java zoneddatetime toEpochSecond without converting to local time

问题

我有一个数据集,其时间为东部标准时间(EST),不考虑任何夏令时调整。
每个日期时间从字符串中读取,并使用以下代码创建带时区信息的日期时间:

ZonedDateTime java.time.ZonedDateTime.of(int year, int month, int dayOfMonth, int hour, int minute, int second, int nanoOfSecond, ZoneId zone)

其中时区使用 ZoneId.of("America/New_York")

我需要将这些日期时间转换为Epoch秒,但内置的 toEpochSecond 方法会转换为我的本地时间,而我的本地时间是夏令时调整后的英国夏令时(BST)。因此,时间戳会相差四到五个小时,具体取决于年份的不同。是否有一种方法可以获取不考虑任何本地时间的Unix时间戳,以便时间戳与原始字符串中的日期时间匹配?

英文:

I have a dataset that is in EST time without any daylight saving.
Each datetime is read from string and a zonedDatetime is created using

ZonedDateTime java.time.ZonedDateTime.of(int year, int month, int dayOfMonth, int hour, int minute, int second, int nanoOfSecond, ZoneId zone)

with a ZoneId.of("America/New_York");

I need to convert these to an epoch second but the built in toEpochSecond method converts to my local time which is BST with day light saving. As a result the timestamps are four to five hours off depending on time of year. Is there a way to get a unix timestamp that does not take into account any local time so the timestamp matches the datetime in the original string?

答案1

得分: 0

我需要将这些转换为以秒为单位的纪元时间,但内置的 toEpochSecond 方法会转换为我的本地时间,即英国夏令时,根据一年中的时间不同,时间戳会偏差四到五个小时。

你肯定是在做一些根本错误的事情。检查以下代码的输出,你会发现没有任何区别。

import java.time.Instant;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
import java.util.Locale;

public class Main {
    public static void main(String[] args) {
        // 格式化器忽略纳秒
        DateTimeFormatter formatter = new DateTimeFormatterBuilder()
                                        .appendPattern("uuuu-MM-dd'T'HH:mm:ssXXX")
                                        .optionalStart()
                                        .appendLiteral('[')
                                        .parseCaseSensitive()
                                        .appendZoneRegionId()
                                        .appendLiteral(']')
                                        .toFormatter(Locale.ENGLISH);

        // 给定的时区
        ZoneId zone = ZoneId.of("America/New_York");

        ZonedDateTime zdtNow = ZonedDateTime.now(zone);
        System.out.println(zdtNow.format(formatter));

        // 从 ZonedDateTime 获取纪元秒
        long epochSecond = zdtNow.toEpochSecond();
        System.out.println(epochSecond);

        // 从纪元秒获取 ZonedDateTime
        ZonedDateTime zdtFromEpochSeconds = Instant.ofEpochSecond(epochSecond).atZone(zone);
        System.out.println(zdtFromEpochSeconds.format(formatter));
    }
}

**输出:**

2020-09-28T17:31:23-04:00[America/New_York]
1601328683
2020-09-28T17:31:23-04:00[America/New_York]
英文:

> I need to convert these to an epoch second but the built in
> toEpochSecond method converts to my local time which is BST with day
> light saving. As a result the timestamps are four to five hours off
> depending on time of year.

You must be doing something fundamentally wrong. Check the output of the following code and you will find that there is no difference.

import java.time.Instant;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
import java.util.Locale;

public class Main {
	public static void main(String[] args) {
		// Formatter ignoring nanoseconds
		DateTimeFormatter formatter = new DateTimeFormatterBuilder()
						                .appendPattern("uuuu-MM-dd'T'HH:mm:ssXXX")
						                .optionalStart()
						                .appendLiteral('[')
						                .parseCaseSensitive()
						                .appendZoneRegionId()
						                .appendLiteral(']')
						                .toFormatter(Locale.ENGLISH);

		// The given time-zone
		ZoneId zone = ZoneId.of("America/New_York");

		ZonedDateTime zdtNow = ZonedDateTime.now(zone);
		System.out.println(zdtNow.format(formatter));

		// Epoch seconds from ZonedDateTime
		long epochSecond = zdtNow.toEpochSecond();
		System.out.println(epochSecond);

		// ZonedDateTime from epoch seconds
		ZonedDateTime zdtFromEpochSeconds = Instant.ofEpochSecond(epochSecond).atZone(zone);
		System.out.println(zdtFromEpochSeconds.format(formatter));
	}
}

Output:

2020-09-28T17:31:23-04:00[America/New_York]
1601328683
2020-09-28T17:31:23-04:00[America/New_York]

答案2

得分: 0

将ZonedDateTime转换为Unix epoch时间戳

首先将其转换为java.time.Instant,然后将区域偏移设置为UTC,然后将其转换为epoch秒,如下所示:

zonedDateTime.toInstant().atZone(ZoneOffset.UTC).toEpochSecond();

注意:变量zonedDateTime的类型为java.time.ZonedDateTime,在将其转换为以秒为单位的“Unix epoch时间戳”之前,它可以位于任何时区。

英文:

To convert ZonedDateTime to Unix epoch time stamp

Convert first to java.time.Instant and then set zone offset to UTC, before converting it to epoch seconds, see below:

zonedDateTime.toInstant().atZone(ZoneOffset.UTC).toEpochSecond();

Note: The variable zonedDateTime is of type java.time.ZonedDateTime and can be in any time zone before converting it to "Unix epoch time stamp" in seconds.

huangapple
  • 本文由 发表于 2020年9月29日 03:10:52
  • 转载请务必保留本文链接:https://go.coder-hub.com/64108218.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定