import java.time.*;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Locale;
import java.util.Map;

public class TestTime {
    public static final boolean SORT_BY_REGION = false;

    public static void main(String[] args)
    {
        LocalDateTime date1 = LocalDateTime.now();
        System.out.println("date1: " + date1);
        LocalDateTime date2 = LocalDateTime.of(1995, 7, 22, 20, 15);
        System.out.println("date2: " + date2);
        LocalDate date3 = LocalDate.of(2001, 1, 19);
        System.out.println("date3: " + date3);
        ZonedDateTime date4 = ZonedDateTime.now();
        System.out.println("date4: " + date4);
        ZonedDateTime date5 = ZonedDateTime.now(ZoneId.of("GMT-3"));
        System.out.println("date5: " + date5);


        // DateTimeFormatter

        // Default pattern
        ZonedDateTime date6 = ZonedDateTime.parse("2020-01-14T19:15:00-03:00[America/Buenos_Aires]");
        System.out.println("date6: " + date6);

        // Custom pattern
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd hh:mm:ss a XXX", Locale.ENGLISH);
        ZonedDateTime date7 = ZonedDateTime.parse("2014-03-27 10:15:30 AM -07:00", formatter);
        System.out.println("date7: " + date7);

        DateTimeFormatter formatter1 = DateTimeFormatter.ofPattern("E, d MMM yyyy HH:mm:ss z");
        ZonedDateTime date8 = ZonedDateTime.parse("Mon, 1 Apr 2019 11:05:30 GMT", formatter1);
        System.out.println("date8: " + date8);

        // Display all ZoneId and its UTC offset
        // https://mkyong.com/java8/java-display-all-zoneid-and-its-utc-offset/
        Map<String, String> sortedMap = new LinkedHashMap<>();

        Map<String, String> allZoneIdsAndItsOffSet = getAllZoneIdsAndItsOffSet();

        // sort map by key
        if (SORT_BY_REGION) {
            allZoneIdsAndItsOffSet.entrySet().stream()
                    .sorted(Map.Entry.comparingByKey())
                    .forEachOrdered(e -> sortedMap.put(e.getKey(), e.getValue()));
        }
        else {
            // sort by value, descending order
            allZoneIdsAndItsOffSet.entrySet().stream()
                    .sorted(Map.Entry.<String, String>comparingByValue().reversed())
                    .forEachOrdered(e -> sortedMap.put(e.getKey(), e.getValue()));
        }

        // print map
        sortedMap.forEach((k, v) ->
        {
            String out = String.format("%35s (UTC%s) %n", k, v);
            System.out.printf(out);
        });

        System.out.println("\nTotal Zone IDs " + sortedMap.size());
    }

    private static Map<String, String> getAllZoneIdsAndItsOffSet()
    {

        Map<String, String> result = new HashMap<>();

        LocalDateTime localDateTime = LocalDateTime.now();

        for (String zoneId : ZoneId.getAvailableZoneIds()) {

            ZoneId id = ZoneId.of(zoneId);

            // LocalDateTime -> ZonedDateTime
            ZonedDateTime zonedDateTime = localDateTime.atZone(id);

            // ZonedDateTime -> ZoneOffset
            ZoneOffset zoneOffset = zonedDateTime.getOffset();

            //replace Z to +00:00
            String offset = zoneOffset.getId().replaceAll("Z", "+00:00");

            result.put(id.toString(), offset);

        }

        return result;
    }
}
