gmalija
gmalija

Reputation: 35

Daylight Saving Time in Android kotlin

I'm trying to get the date for next Daylight Saving Time, but I can't. What I need, for example is to get this date: Sunday, 28 de March 2021, 2:00:00

-> Here I'm getting the date: https://www.timeanddate.com/time/change/spain/madrid

I know TimeZone have the functions observesDaylightTime and inDaylightTime.
But what I need is the date, not if is in range or not.

I also know in iOS(swift) there is a function for this: TimeZone.current.nextDaylightSavingTimeTransition

Does anyone know how to get this date?

Thanks!!

Upvotes: 2

Views: 2316

Answers (3)

Anonymous
Anonymous

Reputation: 86296

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

You are really asking for an imaginary time. I will give you that.

How imaginary? We popularly say that we are turning clocks forward from 2 to 3. The page on timeanddate.com that you are linking to is more precise in its wording:

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

Notice: about to reach. What this means is that 1 minute after 01:59 it is 03:00. There is no 02:00 this night.

But for ordinary humans that don’t need this precision of usage, the transition happens at 2. And the ZoneRules class also wisely used in the other answers can give you this imaginary time:

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

Output is:

2021-03-28T02:00

Upvotes: 1

Arvind Kumar Avinash
Arvind Kumar Avinash

Reputation: 79095

This answer complements the correct answer by deHaar.

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

As per the link you have posted, it should be Sunday, 28 March 2021, 03:00:00.

java.time

It is recommended to use java.time, the modern Date-Time API for date/time operations.

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));
    }
}

Output:

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

Learn more about java.time, the modern Date-Time API* from Trail: Date Time.


* For any reason, if you have to stick to Java 6 or Java 7, you can use 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 How to use ThreeTenABP in Android Project.

Upvotes: 1

deHaar
deHaar

Reputation: 18568

There is java.time you can make us of in Kotlin.

What you need is basically a ZoneOffsetTransition, which represents a change concerning the time offset from UTC.

Here's a small example I tried in the 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());
}

The result of this (lastly executed at 2021-06-03):

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

Please note that this will exclusively work in zones that actually have daylight saving times...

From the 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.

Upvotes: 4

Related Questions