Android kotlin 中的夏令时

Daylight Saving Time in Android kotlin

我正在尝试获取下一个夏令时的日期,但我做不到。 例如,我需要的是获取此日期: 2021 年 3 月 28 日,星期日,2:00:00

-> 我在这里获取日期: https://www.timeanddate.com/time/change/spain/madrid

我知道 TimeZone 有函数 observesDaylightTimeinDaylightTime
但我需要的是日期,而不是是否在范围内。

我也知道 iOS(swift) 中有一个函数:TimeZone.current.nextDaylightSavingTimeTransition

有谁知道如何得到这个日期?

谢谢!!

您可以在 Kotlin 中使用 java.time

你需要的基本上是一个 ZoneOffsetTransition,它代表了一个关于与 UTC 的时间偏移的变化。

这是我在 Kotlin Playground 中尝试的一个小例子:

import java.time.Instant
import java.time.LocalDate
import java.time.ZoneId
import java.time.zone.ZoneOffsetTransition
import java.time.zone.ZoneRules

fun main() {
    // create your desired zone
    val madridZoneId = ZoneId.of("Europe/Madrid");

    // receive the rules of that zone
    var rules = madridZoneId.getRules();

    // receive the next transition from now/today
    var nextTransition = rules.nextTransition(Instant.now());

    // and print it
    println("Next DST change in "
            + madridZoneId
            + ": "
            + nextTransition.getInstant()
                            .atZone(madridZoneId)
                            .toLocalDate());

    // receive the transition after next using the next
    var transitionAfterNext = rules.nextTransition(nextTransition.getInstant());

    // and print that, too
    println("DST change after next in "
            + madridZoneId
            + ": "
            + transitionAfterNext.getInstant()
                                 .atZone(madridZoneId)
                                 .toLocalDate());
}

执行结果(最后执行时间:2021-06-03):

Next DST change in Europe/Madrid: 2021-10-31
DST change after next in Europe/Madrid: 2022-03-27

请注意,这仅适用于实际有夏令时的区域...

来自JavaDocs of ZoneOffsetTransition

If the zone defines daylight savings into the future, then the list will normally be of size two and hold information about entering and exiting daylight savings. If the zone does not have daylight savings, or information about future changes is uncertain, then the list will be empty.

这个答案补充了正确的

What I need, for example is to get this date: Sunday, 28 de March 2021, 2:00:00

根据您发布的 link,应该是 2021 年 3 月 28 日,星期日,03:00:00。

java.time

建议使用 java.time,现代日期时间 API 进行 date/time 操作。

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

public class Main {
    public static void main(String[] args) {
        ZoneId zoneId = ZoneId.of("Europe/Madrid"); 
        
        ZonedDateTime zdt =  zoneId.getRules()
                .previousTransition(Instant.now())
                .getInstant()
                .atZone(zoneId);
        
        System.out.println(zdt);
        
        //Custom format
        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("EEEE, dd MMMM uuuu, HH:mm:ss", Locale.ENGLISH);
        System.out.println(dtf.format(zdt));
    }
}

输出:

2021-03-28T03:00+02:00[Europe/Madrid]
Sunday, 28 March 2021, 03:00:00

详细了解 java.timemodern Date-Time API* from Trail: Date Time


* 无论出于何种原因,如果您必须坚持Java 6 或Java 7,您可以使用ThreeTen-Backport which backports most of the java.time functionality to Java 6 & 7. If you are working for an Android project and your Android API level is still not compliant with Java-8, check Java 8+ APIs available through desugaring and

What I need, for example is to get this date: Sunday, 28 de March 2021, 2:00:00

你真是求虚时。我给你。

如何?我们通常说我们正在将时钟从 2 拨到 3。您链接到的 timeanddate.com 上的页面用词更准确:

When local standard time was about to reach søndag 28. marts 2021, 02:00:00

通知:即将到达。这意味着 01:59 后 1 分钟 03:00。今晚没有02:00

但是对于不需要这种使用精度的普通人来说,转换发生在 2。而其他答案中也明智地使用的 ZoneRules class 可以给你这个假想的时间:

    ZoneOffsetTransition nextTransistion = ZoneId.of("Europe/Madrid")
            .getRules()
            .nextTransition(Instant.parse("2021-01-01T01:00:00Z"));
    LocalDateTime timeBefore = nextTransistion.getDateTimeBefore();
    System.out.println(timeBefore);

输出为:

2021-03-28T02:00