2
\$\begingroup\$

The date 0409·01·MO is New Year’s Day in the Ceres Calendar. Wish everyone and everything in the Asteroid Belt, Jupiter, Saturn and beyond a belated Happy New Year by writing a program to convert Julian Dates (JD) to Ceres Dates using these helpful landmarks:

                                                JD           CMJD      Ceres Date (& Time*)  ISO 8601 (approx.)
Start of Ceres calendar                     2309103.500         0.000   0000·01·MO 00:00     1610
Start of JD calendar                              0.000  -2309103.500  -6344·17·MO           4713 BCE
Earliest recorded eclipse                    501822.000  -1807281.500  -4966·49·SU           3339 BCE
Battle of Megiddo                           1189360.000  -1119743.500  -3077·41·FR           1456 BCE
Battle of Halys                             1507900.000   -801203.500  -2202·47·WE            584 BCE
Alexander the Great (b)                     1591596.000   -717507.500  -1972·43·SU            355 BCE
Crab Nebula supernova                       2106216.000   -202887.500  -0558·33·MO           1054
Discovery of Galilean moons                 2309107.000         3.500   0000·01·TH           1610
Discovery of Titan by Huygens               2325616.000     16512.500   0045·19·SU           1655
Discovery of Uranus by Herschel             2371629.000     62525.500   0171·41·TU           1781
Discovery of Ceres by Piazzi                2378862.000     69758.500   0191·34·TH           1801
Discovery of Pallas by Olbers               2379313.000     70209.500   0192·46·SU           1802
Discovery of Juno by Harding                2380201.000     71097.500   0195·17·SA           1804
Discovery of Vesta by Olbers                2381140.000     72036.500   0197·47·SU           1807
Discovery of Astraea by Hencke              2395274.000     86170.500   0236·39·MO           1845
Discovery of Neptune by Galle & Le Verrier  2395563.000     86459.500   0237·28·WE           1846
First Nobel Prizes awarded                  2415729.000    106625.500   0292·49·TU           1901-12-10
Archduke Franz Ferdinand (d)                2420312.000    111208.500   0305·27·SU           1914-06-28
Discovery of Pluto by Tombaugh              2426054.000    116950.500   0321·16·TU           1930-03-18
Hiroshima bombing                           2431673.469    122569.969   0336·38·SU 23:15     1945-08-05
Dawn probe started exploration of Ceres     2457088.028    147984.528   0406·29·FR 12:40     2015-03-06
Gravitational waves first detected by LIGO  2457279.910    148176.410   0407·05·MO 09:50     2015-09-14
New Year’s Day 0409                         2457980.000    148876.500   0409·01·MO 12:00     2017-08-14

CMJD stands for Ceres Modified JD, a convenient offset. CMJD is related to JD by the formula:

CMJD = JD - 2309103.5

The Ceres Calendar has 52 weeks (01 - 52) of seven days, with Monday (MO) as the first day of the week, the rest are TU, WE, TH, FR, SA, & SU and the time synchronized to UTC formatted as HH:MM or HH:MM:SS. There are no leap days in the Ceres Calendar.

* The Ceres Dates lacking times are only known to the day, so as a convention the middle of the day 12:00 is chosen as the time. Displaying 12:00 for these cases is perfectly acceptable.

Note that the Calendar starts on the Monday before Galileo discovered his satellites, that’s to have the start of the calendar on a Monday to correspond to the ISO 8601 start of the week. The discovery of the Galilean Satellites is more important to them than the Discovery of Ceres but not so important as to mess up the start of the week or the start of the year! That’s just how they roll!

Your program must convert JD ≥ 0.000 to Ceres Date in the format above, using - (U+2212 MINUS SIGN) and · (U+00B7 MIDDLE DOT) as required. Especially for those using ASCII-only languages, you can substitute ~ (U+007E TILDE) and * (U+002A ASTERISK) for the minus sign and middle dot, respectively. The format for dates beyond 9999·52·SU is undefined.

Here’s a handy page to convert to Julian Dates and lots of other useful information.

This is , so shortest answer in bytes wins.

\$\endgroup\$
10
  • 4
    \$\begingroup\$ Bonus points for doing it in Ceres: TIO \$\endgroup\$
    – hyper-neutrino
    Aug 13, 2017 at 16:23
  • \$\begingroup\$ "with seven days" lists only six EDIT: I see SU in the landmarks list, so must be that that is missing. \$\endgroup\$ Aug 13, 2017 at 16:26
  • 3
    \$\begingroup\$ The requirement for a subtraction sign is rather strange for a negative number, hyphen-minus (U+002D) would be more appropriate. \$\endgroup\$ Aug 13, 2017 at 17:19
  • 1
    \$\begingroup\$ @JonathanAllan - thanks for catching missed SU, and apparently the dedicated MINUS SIGN is “more correct” for subtraction operations and negative numbers! \$\endgroup\$
    – user15259
    Aug 13, 2017 at 19:02
  • 1
    \$\begingroup\$ @Notatree - Have added provisions to allow substitutions of ~ (U+007E TILDE) and * (U+002A ASTERISK) for the minus sign and middle dot, respectively. \$\endgroup\$
    – user15259
    Aug 14, 2017 at 13:01

2 Answers 2

3
\$\begingroup\$

Jelly, 92 bytes

Definitely beatable by languages with built-in time-formatting or even just better string-formatting.

%1×⁽¢Ẓd60
_“#ḟf’_.µd364Ad0¦7Ẏ;ÇḞ‘2¦ị3¦“TUWETHFRSASUMO”s2¤Ṛ€o0ẋ⁽¡Ḳḃ4¤¤U⁽œọ;“ṢṢ :‘¤Ọ¤żFḊ⁸Ṡ>-¤¡

A full program accepting a single argument (decimal number representation) and printing the result.

Try it online!

How?

%1×⁽¢Ẓd60 - Link 1, get hours and minutes portion of days: number (of days)
%1        - modulo by one - get the fractional part
   ⁽¢Ẓ    - base 250 number = 1440 (that's 60*24)
  ×       - multiply
      d60 - divmod 60 (integer divide by sixty and yield result and remainder)

_“#ḟf’_.µd364Ad0¦7Ẏ;ÇḞ‘2¦ị3¦“TUWETHFRSASUMO”s2¤Ṛ€o0ẋ⁽¡Ḳḃ4¤¤U⁽œọ;“ṢṢ :‘¤Ọ¤żFḊ⁸Ṡ>-¤¡
          - Main link: number, JulianDate -- breaking this down into parts...

_“#ḟf’_.µ - Main link part 1 (get the CMJD): number, JulianDate
 “#ḟf’    - base 250 number = 2309103
_         - subtract from JulianDate
      _.  - subtract a half
        µ - monadic chan separation, call that CMJD

d364Ad0¦7Ẏ;ÇḞ‘2¦ - Main link part 2 (get the numeric parts): number, CMJD
d364             - divmod 364 (integer divide by 364 and yield result and remainder)
    A            - absolute value (removes the sign from the year part)
       ¦         - sparse application:
      0          - ...to index: zero (rightmost - the remainder)
     d  7        - ...action: divmod 7 (integer divide by 7 and yield result and remainder)
         Ẏ       - tighten (to a list of three items)
           Ç     - call the last link (1) as a monad with argument CMJD
          ;      - concatenate (now we have floats [abs(Y.0), W.0, D.0, H.0, M.x])
            Ḟ    - floor (vectorises) (yielding ints [abs(Y), W, D, H, M]
               ¦ - sparse application:
              2  - ...to index: 2 (W)
             ‘   - ...action: increment (CD weeks are 1-indexed, W is 0 indexed)

ị3¦“TUWETHFRSASUMO”s2¤ - Main link part 3 (make the day-string): result of part 2
  ¦                    - sparse application:
 3                     - ...to index: 3 (D)
ị                      - ...action: index into:
                     ¤ -   nilad followed by link(s) as a nilad:
   “TUWETHFRSASUMO”    -     list of characters = "TUWETHFRSASUMO"
                   s2  -     split into chunks of length two
                       -     (note: D=0 yields "MO" due to 1-based & modular indexing)

Ṛ€o0ẋ⁽¡Ḳḃ4¤¤U - Main link part 4 (pad parts with zeros): result of part 3
Ṛ€            - reverse each (implicit decimal-list, so reverse of 289 is [9,8,2])
           ¤  - nilad followed by link(s) as a nilad:
   0          -   zero
          ¤   -   nilad followed by link(s) as a nilad:
     ⁽¡Ḳ      -     base 250 number = 1178
        ḃ4    -     convert to bijective-base 4 = [4,2,1,2,2]
    ẋ         -   repeat = [[0,0,0,0],[0,0],[0],[0,0],[0,0]]
  o           - logical or (vectorises) (yielding the reversed zero padded entries)
            U - upend (reverse each - everything is already a list so not Ṛ€)
              -   now we have something like: [[Ya,Yb,Yc,Yd],[Wa,Wb],['Da','Db'],[ha,hb],[ma,mb]]

⁽œọ;“ṢṢ :‘¤Ọ¤ż - Main link part 5 (include the separators): result of part 4
            ¤  - nilad followed by link(s) as a nilad:
          ¤    -   nilad followed by link(s) as a nilad:
⁽œọ            -     base 250 literal = 8722
    “ṢṢ :‘     -     code-page indices = [183,183,32,58]
   ;           -     concatenate = [8722,183,183,32,58]
           Ọ   -   covert ordinals to characters = "−·· :"
             ż - zip with the result from part 4, i.e. [['−',[Ya,Yb,Yc,Yd]],['·',[Wa,Wb]],['·',['Da','Db']],[' ',[ha,hb]],[':',[ma,mb]]]

FḊ⁸Ṡ>-¤¡ - Main link part 6 (remove the sign if need be): result from part 5
F        - flatten the result from part 5 into a single list: ['−',Ya,Yb,Yc,Yd,'·',Wa,Wb,'·','Da','Db',' ',ha,hb,':',ma,mb]
       ¡ - repeat:
 Ḋ       - ...action: dequeue (remove first element)
      ¤  - ...number of times: nilad followed by link(s) as a nilad:
  ⁸      -   chain's left argument = CMJD
   Ṡ     -  sign (-1 if less than 0, 0 if equal to 0, 1 if greater than 0)
    >-   -  greater than -1?
         - implicit print
\$\endgroup\$
4
  • 1
    \$\begingroup\$ 92 bytes 0.o this isn't the Jelly I'm used to \$\endgroup\$
    – Stephen
    Aug 14, 2017 at 21:12
  • \$\begingroup\$ Me neither, many things lacking really: not just the (mentioned) time formatting and string formatting, but also mixed-radix conversion which is the reason for repeatedly using sparse application of divmod here. \$\endgroup\$ Aug 14, 2017 at 21:16
  • \$\begingroup\$ TUWETHFRSASUMO - TUESDAY! WEDNESDAY! THURSDAY! FRIDAY! SATURDAY! SUMO! SUMO! SUMO! \$\endgroup\$ Aug 15, 2017 at 1:50
  • \$\begingroup\$ Funnily enough I tried using dictionary compressions, and the word sumo, but can't actually get fewer bytes (need to uppercase it usually for 2 bytes). Mmmm Satsumos. \$\endgroup\$ Aug 15, 2017 at 1:53
1
\$\begingroup\$

Ruby, 120 bytes

Despite being a language with built-in time formatting and string formatting, I still can't beat the Jelly answer...

->n{n-=2309103.5;Time.at((n%7+4)*86400).strftime('%04d·%02d·%%^a %%H:%%M'%[n/364,n%364/7+1]).sub(/. /,' ').tr ?-,?−}

Try it online!

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.