How to find all Instants which correspond to the given LocalDateTime and ZoneId?

Viewed 459

When converting Instant to LocalDateTime it may happen that several different Instants are converted into the same LocalDateTime. Eg. in time zones with day light saving time.

My question is whether it's possible to write a general function which works for any ZoneId and LocalDateTime and returns all Instants which are in the given time zone mapped to the given LocalDateTime:

List<Instant> localToInstants(LocalDateTime dt, ZoneId zone)
4 Answers

Yes ✔️

Edit

M. Prokhorov’s idea of using ZoneRules.getValidOffset() gives more elegant code than I had in my original answer. Here’s a version that returns a list of Instants as requested:

public static List<Instant> localToInstants(LocalDateTime dt, ZoneId zone) {
    return zone.getRules()
            .getValidOffsets(dt)
            .stream()
            .map(dt::atOffset)
            .map(OffsetDateTime::toInstant)
            .collect(Collectors.toList());
}

Let’s try it out on a couple of non-trivial examples. Malta will transition to summer time on March 28. At 2 AM the clocks are turned forward to 3. So the time 2:30 does not exist on this day. Which means that we expect an empty list from the following call:

    LocalDateTime dt = LocalDateTime.of(2021, Month.MARCH, 28, 2, 30);
    System.out.println(localToInstants(dt, ZoneId.of("Europe/Malta")));

Output is indeed:

[]

This is Java’s way of printing an empty list. How it works: Since the time does not exist, ZoneRules.getValidOffsets() returns an empty list. The rest is boring: There are no offsets to convert to OffsetDateTime and further to Instant, so the empty list is returned.

My other example is from Eater Island. According to my Java 9 summer time will end on May 8. At 22 the clocks will be turned back to 21. So the time 21:30 occurs twice. Let’s see:

    LocalDateTime dt = LocalDateTime.of(2021, Month.MAY, 8, 21, 30);
    System.out.println(localToInstants(dt, ZoneId.of("Pacific/Easter")));

[2021-05-09T02:30:00Z, 2021-05-09T03:30:00Z]

Since the UTC offset changes from -05:00 to -06:00, the instants are correct. In this case getValidOffsets() returned two valid offsets, -05:00 and -06:00, so the code produced two OffsetDateTime objects which were in turn converted to two different Instant objects.

Original answer

I am letting this stand in case anyone is interested in getting the appropriate ZonedDateTime objects.

public static List<Instant> localToInstants(LocalDateTime dt, ZoneId zone) {
    return Stream.of(dt.atZone(zone).withEarlierOffsetAtOverlap(),
                     dt.atZone(zone).withLaterOffsetAtOverlap())
            .filter(zdt -> zdt.toLocalDateTime().equals(dt))
            .map(ZonedDateTime::toInstant)
            .distinct()
            .collect(Collectors.toList());
}

Let’s try it out on a couple of non-trivial examples. Malta will transition to summer time on March 28. At 2 AM the clocks are turned forward to 3. So the time 2:30 does not exist on this day. Which means that we expect an empty list from the following call:

    LocalDateTime dt = LocalDateTime.of(2021, Month.MARCH, 28, 2, 30);
    System.out.println(localToInstants(dt, ZoneId.of("Europe/Malta")));

Output is indeed:

[]

This is Java’s way of printing an empty list. How it works: Since the time does not exist, dt.atZone(zone) gives us 3:30 instead of 2:30. Java adds the length of the gap, one hour as usual for a summer time transition. The calls to withEarlierOffsetAtOverlap() and withLaterOffsetAtOverlap() make no difference in this case (I will return to them), so we just get the same ZonedDateTime twice. The call to filter() is what makes the difference: we convert ZonedDateTime back to LocalDateTime and discover that we didn’t get the same time, therefore we discard the results. The rest is boring: there are no ZonedDateTimes to convert to Instant, so we end up with an empty list.

My other example is from Eater Island. According to my Java 9 summer time will end on May 8. At 22 the clocks will be turned back to 21. So the time 21:30 occurs twice. Let’s see:

    LocalDateTime dt = LocalDateTime.of(2021, Month.MAY, 8, 21, 30);
    System.out.println(localToInstants(dt, ZoneId.of("Pacific/Easter")));

[2021-05-09T02:30:00Z, 2021-05-09T03:30:00Z]

Since the UTC offset changes from -05:00 to -06:00, the instants are correct. How it works: here’s where the calls to withEarlierOffsetAtOverlap() and withLaterOffsetAtOverlap() come into play. dt.atZone(zone) gives us one of the options (2021-05-08T21:30-05:00[Pacific/Easter], so the earlier one, but no sane person remembers that by heart). Since Java knows that there’s an overlap at this time, withEarlierOffsetAtOverlap() and withLaterOffsetAtOverlap() give us the two different possibilities. Since both convert back to the correct LocalDateTime, nothing is filtered out. And since both are different instants, distinct() does not filter anything out either. We end up with two Instant objects.

Documetation link

ZoneRules.getValidOffsets()

For a given pair of a LocalDateTime and a ZoneId, all the instants in the list will have the same value and therefore there is no use of creating such a list. I believe what you want is the list of ZonedDateTime having the same value for that pair which you can get as follows:

// ZonedDateTime for the given pair of LocalDateTime and ZoneId
ZonedDateTime zdt = dt.atZone(zone);
ZoneOffset offset = zdt.getOffset();

return ZoneId
        .getAvailableZoneIds()                       // List of timezone names
        .stream()
        .map(tz -> dt.atZone(ZoneId.of(tz)))         // Map the timezone to ZonedDateTime for dt
        .filter(zt -> zt.getOffset().equals(offset)) // Keep only those ZonedDateTimes whose offset is equal to that of zdt
        .collect(Collectors.toList());

Demo:

import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;
import java.util.List;
import java.util.stream.Collectors;

public class Main {
    public static void main(String[] args) {
        // Test
        ZoneId zoneId = ZoneId.of("America/New_York");
        LocalDateTime dt = LocalDateTime.now(zoneId);
        localToZonedDateTimes(dt, zoneId).forEach(System.out::println);
    }

    static List<ZonedDateTime> localToZonedDateTimes(LocalDateTime dt, ZoneId zone) {
        // ZonedDateTime for the given pair of LocalDateTime and ZoneId
        ZonedDateTime zdt = dt.atZone(zone);
        ZoneOffset offset = zdt.getOffset();

        return ZoneId
                .getAvailableZoneIds()                       // List of timezone names
                .stream()
                .map(tz -> dt.atZone(ZoneId.of(tz)))         // Map the timezone to ZonedDateTime for dt
                .filter(zt -> zt.getOffset().equals(offset)) // Keep only those ZonedDateTimes whose offset is equal to that of zdt
                .collect(Collectors.toList());
    }
}

Output:

2021-03-12T16:48:42.368606-05:00[America/Panama]
2021-03-12T16:48:42.368606-05:00[America/Indiana/Petersburg]
2021-03-12T16:48:42.368606-05:00[America/Eirunepe]
2021-03-12T16:48:42.368606-05:00[America/Grand_Turk]
2021-03-12T16:48:42.368606-05:00[Cuba]
2021-03-12T16:48:42.368606-05:00[Etc/GMT+5]
2021-03-12T16:48:42.368606-05:00[Pacific/Easter]
2021-03-12T16:48:42.368606-05:00[America/Fort_Wayne]
2021-03-12T16:48:42.368606-05:00[America/Havana]
2021-03-12T16:48:42.368606-05:00[America/Porto_Acre]
2021-03-12T16:48:42.368606-05:00[US/Michigan]
2021-03-12T16:48:42.368606-05:00[America/Louisville]
2021-03-12T16:48:42.368606-05:00[America/Guayaquil]
2021-03-12T16:48:42.368606-05:00[America/Indiana/Vevay]
2021-03-12T16:48:42.368606-05:00[America/Indiana/Vincennes]
2021-03-12T16:48:42.368606-05:00[America/Indianapolis]
2021-03-12T16:48:42.368606-05:00[America/Iqaluit]
2021-03-12T16:48:42.368606-05:00[America/Kentucky/Louisville]
2021-03-12T16:48:42.368606-05:00[EST5EDT]
2021-03-12T16:48:42.368606-05:00[America/Nassau]
2021-03-12T16:48:42.368606-05:00[America/Jamaica]
2021-03-12T16:48:42.368606-05:00[America/Atikokan]
2021-03-12T16:48:42.368606-05:00[America/Kentucky/Monticello]
2021-03-12T16:48:42.368606-05:00[America/Coral_Harbour]
2021-03-12T16:48:42.368606-05:00[America/Cayman]
2021-03-12T16:48:42.368606-05:00[Chile/EasterIsland]
2021-03-12T16:48:42.368606-05:00[America/Indiana/Indianapolis]
2021-03-12T16:48:42.368606-05:00[America/Thunder_Bay]
2021-03-12T16:48:42.368606-05:00[America/Indiana/Marengo]
2021-03-12T16:48:42.368606-05:00[America/Bogota]
2021-03-12T16:48:42.368606-05:00[SystemV/EST5]
2021-03-12T16:48:42.368606-05:00[US/Eastern]
2021-03-12T16:48:42.368606-05:00[Canada/Eastern]
2021-03-12T16:48:42.368606-05:00[America/Port-au-Prince]
2021-03-12T16:48:42.368606-05:00[America/Nipigon]
2021-03-12T16:48:42.368606-05:00[Brazil/Acre]
2021-03-12T16:48:42.368606-05:00[US/East-Indiana]
2021-03-12T16:48:42.368606-05:00[America/Cancun]
2021-03-12T16:48:42.368606-05:00[America/Lima]
2021-03-12T16:48:42.368606-05:00[America/Rio_Branco]
2021-03-12T16:48:42.368606-05:00[America/Detroit]
2021-03-12T16:48:42.368606-05:00[Jamaica]
2021-03-12T16:48:42.368606-05:00[America/Pangnirtung]
2021-03-12T16:48:42.368606-05:00[America/Montreal]
2021-03-12T16:48:42.368606-05:00[America/Indiana/Winamac]
2021-03-12T16:48:42.368606-05:00[America/New_York]
2021-03-12T16:48:42.368606-05:00[America/Toronto]
2021-03-12T16:48:42.368606-05:00[SystemV/EST5EDT]

Learn more about the modern date-time API from Trail: Date Time.

For any given pair of LocalDateTime and ZoneId, there is only one Instant - because Instant is a moment in UTC offset, the +0:0.

You're probably looking for conversion from LocalDateTime to List<OffsetDateTime>, which is coded something like this:

List<OffsetDateTime> localToOffsets(LocalDateTime ldt, ZoneId zone) {
    ZoneRules rules = zone.getRules();

    return rules.getValidOffsets(ldt).stream()
        .map(ldt::atOffset)
        .collect(Collectors.toList());
}

Loop all time zones, assigning each as the context for your LocalDateTime. From each ZonedDateTime object produced you can extract an Instant. Some of those Instant objects will represent the same moment, where various time zones happened to share the same offset-from-UTC at that date and time.

enter image description here

In this example code, we start with a particular LocalDateTime. That means a date with time-of-day — inherently ambiguous without the context of a time zone or offset-from-UTC. We place our LocalDateTime in such a context repeatedly, placing in each and every time zone known to the tzdata within our version of Java. The result of placing LocalDateTime in a ZoneId is a ZonedDateTime. We then extract an Instant, effectively adjusting to UTC as Instant is a moment as seen in UTC. We put the Instant object into a Map as the key. For the value of the map, we have a collection of ZonedDateTime objects that report that same instant. So we have a multimap, a map of key Instant to multiple values, a Set of ZonedDateTime objects.

LocalDateTime myLocalDateTime = LocalDateTime.of( 2021 , Month.MARCH , 23 , 15 , 30 , 0 , 0 );
Set < String > zoneNames = ZoneId.getAvailableZoneIds();
NavigableMap < Instant, NavigableSet < ZonedDateTime > > instantToZdts = new TreeMap <>();
for ( String zoneName : zoneNames )
{
    ZoneId z = ZoneId.of( zoneName );
    ZonedDateTime zdt = myLocalDateTime.atZone( z );
    Instant instant = zdt.toInstant();
    //System.out.println( myLocalDateTime + " in " + z + " is " + zdt + " = " + instant );

    instantToZdts.putIfAbsent( instant , new TreeSet <>() );
    instantToZdts.get( instant ).add( zdt );
}

Report the results to console.

System.out.println( "instantToZdts = " + instantToZdts );
System.out.println( "---------------|  " + myLocalDateTime + "  |-----------------------" );
System.out.println( "" ) ;
for ( Instant instant : instantToZdts.keySet() )
{
    Set < ZoneId > zoneIds = instantToZdts.get( instant ).stream().map( zonedDateTime -> zonedDateTime.getZone() ).collect( Collectors.toSet() );
    System.out.println( "Instant: " + instant + " in: " + zoneIds );
    System.out.println( "" );
}

When run.

---------------|  2021-03-23T15:30  |-----------------------

Instant: 2021-03-23T01:30:00Z in: [Pacific/Apia, Pacific/Kiritimati, Etc/GMT-14]

Instant: 2021-03-23T01:45:00Z in: [Pacific/Chatham, NZ-CHAT]

Instant: 2021-03-23T02:30:00Z in: [Antarctica/McMurdo, Pacific/Tongatapu, Pacific/Enderbury, Pacific/Fakaofo, NZ, Antarctica/South_Pole, Pacific/Auckland, Etc/GMT-13]

Instant: 2021-03-23T03:30:00Z in: [Pacific/Funafuti, Pacific/Norfolk, Etc/GMT-12, Asia/Kamchatka, Pacific/Tarawa, Kwajalein, Pacific/Kwajalein, Asia/Anadyr, Pacific/Majuro, Pacific/Wake, Pacific/Nauru, Pacific/Fiji, Pacific/Wallis]

Instant: 2021-03-23T04:30:00Z in: [Australia/Sydney, Australia/LHI, Pacific/Efate, Asia/Magadan, Antarctica/Casey, Antarctica/Macquarie, Australia/Lord_Howe, Australia/Victoria, Etc/GMT-11, Pacific/Bougainville, Asia/Srednekolymsk, Australia/Tasmania, Australia/Currie, Pacific/Pohnpei, Australia/Melbourne, Pacific/Noumea, Australia/Hobart, Pacific/Guadalcanal, Pacific/Ponape, Australia/ACT, Australia/Canberra, Australia/NSW, Pacific/Kosrae, Asia/Sakhalin]

Instant: 2021-03-23T05:00:00Z in: [Australia/Adelaide, Australia/South, Australia/Broken_Hill, Australia/Yancowinna]

Instant: 2021-03-23T05:30:00Z in: [Pacific/Port_Moresby, Asia/Vladivostok, Pacific/Saipan, Asia/Ust-Nera, Antarctica/DumontDUrville, Etc/GMT-10, Pacific/Truk, Australia/Lindeman, Pacific/Chuuk, Australia/Brisbane, Pacific/Guam, Pacific/Yap, Australia/Queensland]

Instant: 2021-03-23T06:00:00Z in: [Australia/North, Australia/Darwin]

Instant: 2021-03-23T06:30:00Z in: [Asia/Pyongyang, Asia/Tokyo, Asia/Yakutsk, Asia/Jayapura, Asia/Dili, Japan, Asia/Khandyga, Pacific/Palau, Asia/Chita, Etc/GMT-9, Asia/Seoul, ROK]

Instant: 2021-03-23T06:45:00Z in: [Australia/Eucla]

Instant: 2021-03-23T07:30:00Z in: [PRC, Singapore, Hongkong, Asia/Hong_Kong, Asia/Taipei, Asia/Ulan_Bator, Asia/Manila, Asia/Irkutsk, Asia/Ujung_Pandang, Asia/Harbin, Asia/Kuching, Asia/Chongqing, Australia/Perth, Asia/Kuala_Lumpur, Asia/Ulaanbaatar, Asia/Chungking, Asia/Macao, Asia/Shanghai, Asia/Brunei, Asia/Macau, Asia/Choibalsan, Australia/West, Asia/Singapore, Asia/Makassar, Etc/GMT-8]

Instant: 2021-03-23T08:30:00Z in: [Asia/Vientiane, Asia/Ho_Chi_Minh, Asia/Tomsk, Asia/Phnom_Penh, Asia/Jakarta, Asia/Hovd, Asia/Barnaul, Asia/Krasnoyarsk, Asia/Pontianak, Asia/Bangkok, Asia/Saigon, Asia/Novokuznetsk, Asia/Novosibirsk, Indian/Christmas, Antarctica/Davis, Etc/GMT-7]

Instant: 2021-03-23T09:00:00Z in: [Asia/Yangon, Indian/Cocos, Asia/Rangoon]

Instant: 2021-03-23T09:30:00Z in: [Asia/Dacca, Asia/Thimbu, Asia/Omsk, Asia/Qostanay, Asia/Almaty, Asia/Dhaka, Indian/Chagos, Asia/Kashgar, Asia/Urumqi, Antarctica/Vostok, Asia/Bishkek, Asia/Thimphu, Etc/GMT-6]

Instant: 2021-03-23T09:45:00Z in: [Asia/Katmandu, Asia/Kathmandu]

Instant: 2021-03-23T10:00:00Z in: [Asia/Calcutta, Asia/Colombo, Asia/Kolkata]

Instant: 2021-03-23T10:30:00Z in: [Asia/Aqtobe, Asia/Samarkand, Indian/Kerguelen, Asia/Oral, Asia/Ashgabat, Asia/Dushanbe, Asia/Aqtau, Asia/Ashkhabad, Asia/Tashkent, Antarctica/Mawson, Asia/Karachi, Asia/Atyrau, Asia/Yekaterinburg, Etc/GMT-5, Asia/Qyzylorda, Indian/Maldives]

Instant: 2021-03-23T11:00:00Z in: [Asia/Kabul, Asia/Tehran, Iran]

Instant: 2021-03-23T11:30:00Z in: [Indian/Mahe, Indian/Mauritius, Europe/Astrakhan, Indian/Reunion, Asia/Yerevan, Europe/Ulyanovsk, Asia/Dubai, Asia/Muscat, Asia/Tbilisi, Europe/Samara, Europe/Saratov, Europe/Volgograd, Etc/GMT-4, Asia/Baku]

Instant: 2021-03-23T12:30:00Z in: [Asia/Aden, Asia/Qatar, Africa/Nairobi, Antarctica/Syowa, Africa/Juba, Asia/Riyadh, Europe/Moscow, Asia/Bahrain, Africa/Mogadishu, Africa/Dar_es_Salaam, Asia/Baghdad, Asia/Kuwait, Africa/Addis_Ababa, Asia/Istanbul, Africa/Djibouti, Europe/Kirov, Africa/Asmara, Africa/Asmera, Europe/Simferopol, Indian/Antananarivo, Africa/Kampala, Indian/Mayotte, W-SU, Turkey, Europe/Istanbul, Etc/GMT-3, Indian/Comoro, Europe/Minsk]

Instant: 2021-03-23T13:30:00Z in: [Europe/Kiev, Asia/Hebron, Egypt, Europe/Zaporozhye, Asia/Nicosia, Africa/Lusaka, Africa/Gaborone, Africa/Maputo, Europe/Kaliningrad, Libya, Africa/Cairo, Africa/Windhoek, Europe/Mariehamn, Africa/Mbabane, Europe/Vilnius, Asia/Gaza, Europe/Chisinau, Asia/Famagusta, Africa/Maseru, Asia/Amman, Africa/Lubumbashi, Europe/Bucharest, Europe/Uzhgorod, Europe/Helsinki, Asia/Beirut, Africa/Harare, Asia/Tel_Aviv, Africa/Kigali, Europe/Sofia, Europe/Tallinn, Africa/Khartoum, EET, Europe/Tiraspol, Africa/Johannesburg, Europe/Nicosia, Asia/Damascus, Africa/Bujumbura, Asia/Jerusalem, Europe/Athens, Africa/Tripoli, Etc/GMT-2, Israel, Africa/Blantyre, Europe/Riga]

Instant: 2021-03-23T14:30:00Z in: [Europe/Ljubljana, Africa/Libreville, Europe/Berlin, Africa/El_Aaiun, Europe/Oslo, Europe/Stockholm, Europe/Budapest, Europe/Bratislava, Europe/San_Marino, Europe/Zagreb, Europe/Copenhagen, Europe/Malta, Europe/Brussels, Europe/Vienna, Africa/Douala, Europe/Busingen, Europe/Warsaw, CET, Africa/Malabo, Etc/GMT-1, Europe/Podgorica, Europe/Skopje, Europe/Paris, Africa/Ndjamena, Europe/Sarajevo, Europe/Tirane, Africa/Bangui, Europe/Luxembourg, Europe/Belgrade, Arctic/Longyearbyen, MET, Africa/Casablanca, Africa/Lagos, Europe/Rome, Africa/Brazzaville, Africa/Luanda, Africa/Porto-Novo, Atlantic/Jan_Mayen, Africa/Ceuta, Africa/Algiers, Europe/Zurich, Europe/Amsterdam, Poland, Europe/Vatican, Europe/Gibraltar, Africa/Kinshasa, Europe/Madrid, Europe/Vaduz, Africa/Niamey, Europe/Prague, Africa/Tunis, Europe/Andorra, Europe/Monaco]

Instant: 2021-03-23T15:30:00Z in: [UTC, UCT, Portugal, Iceland, Zulu, Africa/Ouagadougou, Europe/Lisbon, Etc/Universal, Europe/London, Atlantic/Faeroe, Africa/Dakar, Etc/GMT, Atlantic/Canary, Africa/Lome, Universal, Africa/Freetown, Africa/Sao_Tome, GMT, Greenwich, Etc/GMT-0, Europe/Jersey, GB-Eire, Africa/Bissau, Europe/Belfast, Africa/Abidjan, Atlantic/Reykjavik, Africa/Monrovia, WET, Atlantic/St_Helena, Etc/Greenwich, Etc/GMT0, Africa/Bamako, Eire, Europe/Guernsey, Africa/Timbuktu, Atlantic/Madeira, GB, Africa/Accra, Africa/Conakry, Atlantic/Faroe, Etc/UTC, Etc/UCT, GMT0, Europe/Dublin, Etc/Zulu, Africa/Nouakchott, Europe/Isle_of_Man, Antarctica/Troll, Etc/GMT+0, Africa/Banjul, America/Danmarkshavn]

Instant: 2021-03-23T16:30:00Z in: [America/Scoresbysund, Atlantic/Cape_Verde, Atlantic/Azores, Etc/GMT+1]

Instant: 2021-03-23T17:30:00Z in: [Atlantic/South_Georgia, Brazil/DeNoronha, Etc/GMT+2, America/Miquelon, America/Noronha]

Instant: 2021-03-23T18:00:00Z in: [America/St_Johns, Canada/Newfoundland]

Instant: 2021-03-23T18:30:00Z in: [America/Argentina/San_Juan, America/Cordoba, America/Sao_Paulo, America/Thule, America/Argentina/Ushuaia, America/Mendoza, America/Moncton, America/Santarem, Canada/Atlantic, America/Asuncion, America/Belem, America/Montevideo, America/Argentina/ComodRivadavia, Atlantic/Bermuda, America/Jujuy, America/Fortaleza, America/Argentina/La_Rioja, Brazil/East, America/Recife, America/Buenos_Aires, Antarctica/Palmer, America/Bahia, America/Goose_Bay, America/Argentina/Jujuy, America/Maceio, America/Argentina/Tucuman, America/Argentina/Cordoba, America/Paramaribo, America/Argentina/Mendoza, America/Nuuk, America/Punta_Arenas, America/Araguaina, America/Argentina/Rio_Gallegos, America/Cayenne, Chile/Continental, America/Halifax, America/Argentina/Buenos_Aires, Antarctica/Rothera, America/Catamarca, America/Godthab, America/Argentina/Salta, Etc/GMT+3, America/Argentina/San_Luis, America/Rosario, Atlantic/Stanley, America/Argentina/Catamarca, America/Santiago, America/Glace_Bay]

Instant: 2021-03-23T19:30:00Z in: [America/Indianapolis, America/Cuiaba, America/Iqaluit, America/Curacao, America/Marigot, America/Blanc-Sablon, America/Indiana/Winamac, America/Guyana, America/Martinique, America/Kentucky/Monticello, Brazil/West, America/Boa_Vista, America/Aruba, America/St_Vincent, America/Grenada, America/Puerto_Rico, America/Tortola, America/Porto_Velho, America/Kentucky/Louisville, America/Manaus, America/Port_of_Spain, America/New_York, America/Indiana/Petersburg, America/Indiana/Indianapolis, America/Santo_Domingo, US/Eastern, America/St_Kitts, SystemV/AST4, America/Caracas, America/Dominica, America/Guadeloupe, Canada/Eastern, America/Port-au-Prince, America/St_Barthelemy, America/La_Paz, America/Nipigon, America/Indiana/Vevay, America/Campo_Grande, America/Fort_Wayne, EST5EDT, America/St_Thomas, America/Anguilla, US/East-Indiana, America/Virgin, America/Thunder_Bay, America/Grand_Turk, SystemV/AST4ADT, America/St_Lucia, America/Pangnirtung, America/Montserrat, America/Havana, America/Toronto, America/Indiana/Marengo, US/Michigan, America/Barbados, Cuba, America/Indiana/Vincennes, America/Nassau, America/Kralendijk, America/Antigua, America/Louisville, America/Lower_Princes, America/Montreal, America/Detroit, Etc/GMT+4]

Instant: 2021-03-23T20:30:00Z in: [America/Matamoros, America/Guayaquil, Brazil/Acre, America/North_Dakota/New_Salem, America/Coral_Harbour, America/North_Dakota/Center, America/Winnipeg, America/Indiana/Knox, America/Rankin_Inlet, America/Cancun, America/Cayman, America/Panama, America/North_Dakota/Beulah, CST6CDT, Pacific/Easter, America/Knox_IN, America/Lima, America/Bogota, America/Indiana/Tell_City, America/Menominee, America/Resolute, America/Porto_Acre, US/Central, US/Indiana-Starke, SystemV/EST5, SystemV/EST5EDT, America/Chicago, Chile/EasterIsland, America/Jamaica, Canada/Central, America/Eirunepe, America/Atikokan, America/Rainy_River, America/Rio_Branco, Jamaica, Etc/GMT+5]

Instant: 2021-03-23T21:30:00Z in: [America/Inuvik, America/Yellowknife, America/Regina, America/Boise, America/El_Salvador, America/Costa_Rica, America/Shiprock, America/Denver, America/Guatemala, America/Belize, SystemV/CST6CDT, Mexico/General, America/Swift_Current, America/Bahia_Banderas, America/Managua, Canada/Mountain, America/Cambridge_Bay, Navajo, America/Ojinaga, MST7MDT, America/Monterrey, America/Merida, Pacific/Galapagos, America/Mexico_City, America/Edmonton, US/Mountain, America/Tegucigalpa, Canada/Saskatchewan, Etc/GMT+6, SystemV/CST6]

Instant: 2021-03-23T22:30:00Z in: [America/Tijuana, America/Santa_Isabel, US/Arizona, Canada/Pacific, Canada/Yukon, Mexico/BajaSur, America/Chihuahua, SystemV/MST7MDT, America/Creston, America/Phoenix, America/Dawson_Creek, America/Los_Angeles, America/Whitehorse, America/Ensenada, America/Dawson, America/Mazatlan, PST8PDT, America/Hermosillo, America/Vancouver, SystemV/MST7, Etc/GMT+7, America/Fort_Nelson, US/Pacific, Mexico/BajaNorte]

Instant: 2021-03-23T23:30:00Z in: [America/Anchorage, America/Yakutat, America/Sitka, Etc/GMT+8, America/Metlakatla, Pacific/Pitcairn, SystemV/PST8, SystemV/PST8PDT, America/Juneau, America/Nome, US/Alaska]

Instant: 2021-03-24T00:30:00Z in: [Etc/GMT+9, America/Adak, US/Aleutian, America/Atka, SystemV/YST9, SystemV/YST9YDT, Pacific/Gambier]

Instant: 2021-03-24T01:00:00Z in: [Pacific/Marquesas]

Instant: 2021-03-24T01:30:00Z in: [Etc/GMT+10, Pacific/Honolulu, Pacific/Rarotonga, Pacific/Tahiti, US/Hawaii, Pacific/Johnston, SystemV/HST10]

Instant: 2021-03-24T02:30:00Z in: [Pacific/Pago_Pago, Pacific/Midway, Pacific/Niue, Pacific/Samoa, Etc/GMT+11, US/Samoa]

Instant: 2021-03-24T03:30:00Z in: [Etc/GMT+12]

You asked for:

returns all Instants which are in the given time zone

There is only one Instant per time zone per LocalDateTime. A date with time-of-day can exist only once within a time zone.

Related