mhilton commented on issue #10602:
URL: https://github.com/apache/datafusion/issues/10602#issuecomment-5845897142

   Seeing as there has been some activity around this recently I've been trying 
to think about what reasonable semantics should be for a `date_bin` that 
adjusts for DST changes. These are some suggestions designed to promote 
discussion rather than dictate policy. 
   
   ## 1.  `date_bin`s should never jump backwards
   
   A naive implementation that simply shifts to the timestamp to local time, 
performs the `data_bin` and then shifts back the local time using the timezone 
offset can produce surprising results where the bins overlap the discontinuity. 
Consider the following times when used with such a naive implementation of 
`date_bin(INTERVAL '1 HOUR', t,  '1970-01-01T00:30:00Z')`:
   
   ```
   
+----------------------+------------------------+------------------------+--------------------------+
   | UTC                  | Europe/London          | date_bin (timestamp)   | 
date_bin (timestamp UTC) |
   
+----------------------+------------------------+------------------------+--------------------------+
   | 2026-10-24T23:30:00Z | 2026-10-25T00:30:00+01 | 2026-10-25T00:30:00+01 | 
2026-10-24T23:30:00Z     |
   | 2026-10-24T23:45:00Z | 2026-10-25T00:45:00+01 | 2026-10-25T00:30:00+01 | 
2026-10-24T23:30:00Z     |
   | 2026-10-25T00:00:00Z | 2026-10-25T01:00:00+01 | 2026-10-25T00:30:00+01 | 
2026-10-24T23:30:00Z     |
   | 2026-10-25T00:15:00Z | 2026-10-25T01:15:00+01 | 2026-10-25T00:30:00+01 | 
2026-10-24T23:30:00Z     |
   | 2026-10-25T00:30:00Z | 2026-10-25T01:30:00+01 | 2026-10-25T01:30:00+01 | 
2026-10-25T00:30:00Z     |
   | 2026-10-25T00:45:00Z | 2026-10-25T01:45:00+01 | 2026-10-25T01:30:00+01 | 
2026-10-25T00:30:00Z     |
   | 2026-10-25T01:00:00Z | 2026-10-25T01:00:00+00 | 2026-10-25T00:30:00+01 | 
2026-10-24T23:30:00Z     |
   | 2026-10-25T01:15:00Z | 2026-10-25T01:15:00+00 | 2026-10-25T00:30:00+01 | 
2026-10-24T23:30:00Z     |
   | 2026-10-25T01:30:00Z | 2026-10-25T01:30:00+00 | 2026-10-25T01:30:00+00 | 
2026-10-25T01:30:00Z     |
   | 2026-10-25T01:45:00Z | 2026-10-25T01:30:00+00 | 2026-10-25T01:30:00+00 | 
2026-10-25T01:30:00Z     |
   
+----------------------+------------------------+------------------------+--------------------------+
   ``` 
   
   As can be seen around the discontinuity it is possible for an absolute 
timestamp to be put in a bin earlier than a smaller absolute timestamp. In my 
opinion a `date_bin` implementation should be written to avoid this happening. 
In this particular case I think it would be better for a DST aware `date_bin` 
to follow how UTC would bin the values:
   
   ```
   
+----------------------+------------------------+------------------------+--------------------------+
   | UTC                  | Europe/London          | date_bin (timestamp)   | 
date_bin (timestamp UTC) |
   
+----------------------+------------------------+------------------------+--------------------------+
   | 2026-10-24T23:30:00Z | 2026-10-25T00:30:00+01 | 2026-10-25T00:30:00+01 | 
2026-10-24T23:30:00Z     |
   | 2026-10-24T23:45:00Z | 2026-10-25T00:45:00+01 | 2026-10-25T00:30:00+01 | 
2026-10-24T23:30:00Z     |
   | 2026-10-25T00:00:00Z | 2026-10-25T01:00:00+01 | 2026-10-25T00:30:00+01 | 
2026-10-24T23:30:00Z     |
   | 2026-10-25T00:15:00Z | 2026-10-25T01:15:00+01 | 2026-10-25T00:30:00+01 | 
2026-10-24T23:30:00Z     |
   | 2026-10-25T00:30:00Z | 2026-10-25T01:30:00+01 | 2026-10-25T01:30:00+01 | 
2026-10-25T00:30:00Z     |
   | 2026-10-25T00:45:00Z | 2026-10-25T01:45:00+01 | 2026-10-25T01:30:00+01 | 
2026-10-25T00:30:00Z     |
   | 2026-10-25T01:00:00Z | 2026-10-25T01:00:00+00 | 2026-10-25T01:30:00+01 | 
2026-10-25T00:30:00Z     |
   | 2026-10-25T01:15:00Z | 2026-10-25T01:15:00+00 | 2026-10-25T01:30:00+01 | 
2026-10-25T00:30:00Z     |
   | 2026-10-25T01:30:00Z | 2026-10-25T01:30:00+00 | 2026-10-25T01:30:00+00 | 
2026-10-24T01:30:00Z     |
   | 2026-10-25T01:45:00Z | 2026-10-25T01:30:00+00 | 2026-10-25T01:30:00+00 | 
2026-10-24T01:30:00Z     |
   
+----------------------+------------------------+------------------------+--------------------------+
   ```
   
   ## 2. An `origin_timestamp` parameter without a timezone offset acts as if 
it is in the binned timestamp's timezone
   
   Most implementations I can think of would do this for free anyway, but it is 
worth stating explicitly. If the `origin_timestamp` does not explicitly say 
what time zone it is in then it is treated as if it is in the timezone of the 
value being binned. For example when binning timestamps in the 
`American/Los_Angeles` timezone then an origin timestamp of 
`1970-01-01T00:30:00` works as if it were the absolute value 
`1970-01-01T00:30:00-08:00`.
   
   The default `origin_timestamp` should be defined to be `1970-01-01T00:00:00` 
in local time, which is the start of the year 1970 in that timezone. So for 
`Australia/Adelaide` this will map to `1970-01-01T00:00:00+09:30` or 
`1969-12-31T14:30:00Z`.
   
   If the specified `origin_timestamp` is undefined or ambiguous in the binned 
timestamp's timezone then I think `date_bin` should output an error.
   
   ## 3. A day in a timezone starts at the first instance that reports the date 
as being that day
   
   This might seem self-evident, but it is a looser definition than days start 
at midnight. This in necessary because historically there have been timezones 
where midnight does not exist in local time. For example in `America/Sao_Paulo` 
the timestamp `2018-10-03T23:59:59.999999999-03` jumps straight to 
`2018-10-04T01:00:00.000000000-02`.
   
   A similar rule needs to apply to the start of months. In the same timezone 
`2015-10-31T23:59:59:.999999999-03` jumped straight to 
`2015-11-01T01:00:00.000000000-02`. 
   
   ## 4. The value returned from `date_bin` cannot be after the timestamp being 
binned
   
   The timestamp value output from `date_bin` should be lower than or equal to 
the timestamp being binned. This is another one that might be obvious but the 
arithmetic can get tricky when one starts dealing with negative values.
   
   ## 5. Intervals adjusted for daylight savings should not be adjusted further 
than the offset change
   
   Where an interval stretches over a discontinuity then the interval may be 
grown or shrunk to accommodate the discontinuity. Effort should be made to 
avoid an interval's length being further away from requested than is needed for 
the daylight savings adjustment.
   
   ## 6. Using an `expression` with a timezone is sufficient to opt in to DST 
adjustment
   
   I hold this loosely as it might give confusing results for existing 
`date_bin` users. However the only alternatives I can think of either restrict 
the DST adjustment to intervals specified in months or days, or require an 
additional parameter. Seeing as changing timestamp arrays between two defined 
timezones is simply a metadata change it seems reasonable that users can cast 
to `Timestamp(ns, Some("UTC"))` if they want to avoid DST adjustment.
   
   I haven't actually put much thought into how one would implement all of 
this. I'd be interested to hear any other's thoughts.


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to