2

Compute the number of SI seconds between “2021-01-01 12:56:23.423 UTC” and “2001-01-01 00:00:00.000 UTC” as example.

2 Answers2

3

C++20 can do it with the following syntax:

#include <chrono>
#include <iostream>

int
main()
{
    using namespace std;
    using namespace std::chrono;

    auto t0 = sys_days{2001y/1/1};
    auto t1 = sys_days{2021y/1/1} + 12h + 56min + 23s + 423ms;
    auto u0 = clock_cast<utc_clock>(t0);
    auto u1 = clock_cast<utc_clock>(t1);
    cout << u1 - u0 << '\n';  // with leap seconds
    cout << t1 - t0 << '\n';  // without leap seconds
}

This outputs:

631198588423ms
631198583423ms

The first number includes leap seconds, and is 5s greater than the second number which does not.

This C++20 chrono preview library can do it in C++11/14/17. One just has to #include "date/tz.h", change the y suffix to _y in two places, and add using namespace date;.

Howard Hinnant
  • 206,506
  • 52
  • 449
  • 577
2

My library Time4J can realize this task in Java language. Example using your input:

    ChronoFormatter<Moment> f = 
        ChronoFormatter.ofMomentPattern(
            "uuuu-MM-dd HH:mm:ss.SSS z", 
            PatternType.CLDR, 
            Locale.ROOT, 
            ZonalOffset.UTC);
    Moment m1 = f.parse("2001-01-01 00:00:00.000 UTC");
    Moment m2 = f.parse("2021-01-01 12:56:23.423 UTC");
    
    MachineTime<TimeUnit> durationPOSIX = MachineTime.ON_POSIX_SCALE.between(m1, m2);
    MachineTime<SI> durationSI = MachineTime.ON_UTC_SCALE.between(m1, m2);

    System.out.println("POSIX: " + durationPOSIX); // without leap seconds
    // output: 631198583.423000000s [POSIX]

    System.out.println("SI: " + durationSI); // inclusive 5 leap seconds
    // output: 631198588.423000000s [UTC]
    
    // if you only want to count full seconds...
    System.out.println(SI.SECONDS.between(m1, m2)); 
    // output: 631198588

    // first leap second after 2001
    System.out.println(m1.with(Moment.nextLeapSecond()));
    // output: 2005-12-31T23:59:60Z

The result of 5 seconds difference is in agreement with officially listed leap seconds between the years 2001 and 2021.

In general: This library supports leap seconds only since 1972.

Meno Hochschild
  • 42,708
  • 7
  • 104
  • 126