@martinjuckes 
Providing concrete examples like you did is quite useful. I should probably 
have done so myself well before this. My apologies.

Let's say I am acquiring data once every 10 seconds using a GPS receiver to get 
UTC time stamps. Around the last leap second I will have:
- **`2017-12-31T23:59:40Z`**
- **`2017-12-31T23:59:50Z`**
- **`2017-12-31T23:59:60Z`**
- **`2017-01-01T00:00:09Z`**
- **`2017-01-01T00:00:19Z`**
- **`2017-01-01T00:00:29Z`**

This represents the worst case scenario.

Here is what my time variable will contain using the two new calendars:
- Time variable using **`new calendar a`** (UTC converted to elapsed time 
without taking leap seconds into account)
   - units = "seconds since 2017-12-31 23:59:40"
   - data = [ 0, 10, 20, 29, 39, 49 ]
- Time variable using **`new calendar b`** (UTC time stamps converted to 
elapsed time taking leap seconds into account)
   - units = "seconds since 2017-12-31 23:59:40"
   - data = [ 0, 10, 20, 30, 40, 50 ]

In the first case the time variable encodes an error. This is what makes the 
contents non-metric. Comparison of the intervals before and after the leap 
second yields a value of 10 seconds, but the center interval is 9 seconds. It's 
not that the seconds aren't SI seconds. It's that we have encoded an error. In 
the second case, the time variable contents are fully metric.

What happens if we extract UTC time stamps  from these two different time 
variables? We get:
1. Time variable using **`new calendar a`** (Converted to UTC time stamps 
without taking leap seconds into account)
   - **`2017-12-31T23:59:40Z`**
   - **`2017-12-31T23:59:50Z`**
   - **`2017-01-01T00:00:00Z`** - error here
   - **`2017-01-01T00:00:09Z`**
   - **`2017-01-01T00:00:19Z`**
   - **`2017-01-01T00:00:29Z`**
1. Time variable using **`new calendar a`** (Converted to UTC time stamps 
taking leap seconds into account - requires custom software)
   - **`2017-12-31T23:59:40Z`**
    - **`2017-12-31T23:59:50Z`**
   - **`2017-12-31T23:59:60Z`**
   - **`2017-01-01T00:00:09Z`**
   - **`2017-01-01T00:00:19Z`**
   - **`2017-01-01T00:00:29Z`**
1. Time variable using **`new calendar b`** (Converted to UTC time stamps 
without taking leap seconds into account)
   - **`2017-12-31T23:59:40Z`**
   - **`2017-12-31T23:59:50Z`**
   - **`2017-01-01T00:00:00Z`** - error here
   - **`2017-01-01T00:00:10Z`** - error here
   - **`2017-01-01T00:00:20Z`** - error here
   - **`2017-01-01T00:00:30Z`** - error here
1. Time variable using **`new calendar b`** (Converted to UTC time stamps 
taking leap seconds into account)
   - **`2017-12-31T23:59:40Z`**
    - **`2017-12-31T23:59:50Z`**
   - **`2017-12-31T23:59:60Z`**
   - **`2017-01-01T00:00:09Z`**
   - **`2017-01-01T00:00:19Z`**
   - **`2017-01-01T00:00:29Z`**

In the first case, we get back (except on the leap second) the time stamps that 
were the inputs to the variable. There is an error in the results, but notice 
that if the times were each one second later, you wouldn't see any error in the 
results.

In the second case, the savvy user understands from the calendar used that 
there will be an error in the time stamp on the leap second. That user captures 
that special case with custom software and fixes the one time stamp.

In the third case, the unfortunate user doesn't pay attention to what it means 
to have a variable that uses **`new calendar b`** and converts the metric 
elapsed times to UTC without considering leap seconds. They get a one second 
error that propagates. But they ignored the calendar, so we can't really help 
them.

In the fourth case, the savvy user understands from the calendar used that the 
elapsed times are metric, and that if she wants to get an accurate UTC time 
stamp, she must use a process that is aware of leap seconds. She does so, and 
gets fully correct results back.

The reason for the two different new calendars is that the first, erroneous 
time variable produces correct results (with one exception) if the users are 
only interested in getting time stamps. If they convert the values back to UTC 
time stamps without taking leap seconds into account, they will get back the 
original inputs the vast majority of the time. And that is well sufficient for 
a large number of users.

The second, "correct" time variable produces correct results if the user is 
savvy. Notice that the savvy user can also get correct results from the first 
time variable if they want to. The savvy user can also get exact elapsed times 
from the first variable by adding leap seconds as needed if they need exact 
elapsed time values.
The only truly bad scenario here is the one in which an un-savvy user tries to 
get UTC time stamps from the "correct" time variable without taking leap 
seconds into account.

This is why I have proposed the two new calendars. They allow data producers to 
signal to savvy users how to use the contents. **`new calendar a`** provides 
maximum accommodation of the needs of less savvy users without posing a big 
problem for savvy users that need more. **`new calendar b`** allows data 
producers to be rigorous and exact, and is better from that standpoint. It 
makes life easier for savvy users, but less savvy users might make a mistake 
that will lead to erroneous time stamps. But we can't save people from 
themselves. We can warn them, and I think we should write enough about all of 
this in the CF Conventions document to make it clear, but there are plenty of 
people out there that don't read the manual. I deal with them on a regular 
basis.

-- 
You are receiving this because you commented.
Reply to this email directly or view it on GitHub:
https://github.com/cf-convention/cf-conventions/issues/148#issuecomment-435181134

Reply via email to