Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Date string format that sorted lexicographically ascending is chronologically descending?

Encoding calendar dates as strings in the YYYY-MM-DD format (with or without separators, e.g. 2014-04-21, 2014.04.21 or 20140421) has the following properties:

  • Sorting the strings lexicographically ascending (treating them as simple strings, unaware of what they represent) puts them in chronological order
  • Converting between the calendar date and the string is obvious for humans (2014-04-21 obviously represents April 21, 2014)

Note that for this to work, each component of the date (year, month and day) must always use the same number of characters, with leading zeroes if the number is too small. This means that YYYY can only represent years up to 9999. If we want to represent 5-digit years too, then the date in my example above becomes 02014-04-21.

Question:

Is there a way to encode calendar dates as strings, such that sorting the strings lexicographically ascending puts them in reverse chronological order?

Ideally, it would be easy for a human to convert between the calendar date and the format you suggest, but even if you don't manage this (my solution below doesn't) I still want to know your solution.

If it helps, you may require this restriction:

  • I only need to represent dates between Jan 1, 2001 and Dec 31, 2099.

All I could come up with is this:

  • Pick a Maximum Representable Year ahead of time, e.g. 2100
  • Convert year-month-day to (2100-year), (13-month), (32-day) and add leading zeroes as explained above if any of these 3 numbers is too low.
  • Thus Apr 21, 2014 becomes 86-09-11

The main problem with my solution is that it's not obvious to a human that 86-09-11 represents April 21, 2014.

Notes:

  • I know I can just sort the YYYY-MM-DD strings in descending order. That's not what I'm looking for.
  • Your format doesn't have to represent the year, month and day separately in the string. For example you can encode a date as an integer showing “How many days are left before January 1, 2100” with zero padding to the left.
  • Even if you can't find a format that's easy-to-read by a human, I still want to see your answer and know as many approaches to my question as possible.
  • I'm not looking for a discussion of the month/day ambiguity. I imagine that some people may find 2001-01-02 ambiguous (either Jan 2 or Feb 1). But that doesn't matter here: the humans reading the format will know ahead of time what the format is (in this case YYYY-MM-DD) so there's no ambiguity.
like image 690
Amber Jade Fontana Avatar asked Nov 01 '22 01:11

Amber Jade Fontana


1 Answers

You could use 9's complement -- write down the ISO date and then replace each digit by 9 minus that digit. At least I can apply in my head the encode/decode function (they're the same). I don't understand, however, why you don't just keep some redundant information around, turning 2006-01-02 into HJJD-JI-JH-2006-01-02, deriving 2006-01-02 -> 7993-98-97 -> HJJD-JI-JH by replacing 0 -> A, 1 -> B, 2 -> C, 3 -> D, 4 -> E, 5 -> F, 6 -> G, 7 -> H, 8 -> I, 9 -> J.

like image 127
David Eisenstat Avatar answered Nov 09 '22 06:11

David Eisenstat