I'm a time traveler, and I'm obsessed with the passage of time. I particularly love the moments when the clock hands pass 12, or when I get to flip to the next page of my calendar, or when everyone yells "Happy New Year!"
Please write for me a program to show me how far I am from the last such moment to the next, in the form of a progress bar. For example, if I tell it the time is 09:12, it should print this:
09:00 ####---------------- 10:00
If I tell it the month is May, 1982, it should print this:
1982-01 #######------------- 1983-01
Did I mention I'm a time traveler? I travel to anywhere from the first millisecond of 0 A.D. to the last millisecond of 9999 A.D., so the program needs to handle any date and time in that range.
Input
Input will be in one of the following formats:
YYYY-MM-DDThh:mm:ss.sss
YYYY-MM-DDThh:mm:ss
YYYY-MM-DDThh:mm
YYYY-MM-DDThh
YYYY-MM-DD
YYYY-MM
These are the only formats that need be handled. Each part will have exactly the number of digits shown, which means fractional seconds may have trailing zeroes (e.g.
.120
, never.12
). TheT
is a literal letter "T" delimiting the date from the time. Hours are on a 24-hour clock.Months and days are 1-based (more on this below).
Invalid and out-of-range inputs need not be handled.
At the programmer's discretion, input may have a single trailing newline.
Progress bar math
The program is concerned with the least- and second-least-significant units in the given input. For example, if the input has day-level precision (e.g. 2016-12-14
), the progress bar will indicate what proportion of the days in the input month have elapsed versus what remains.
The progress bar will have 20 units (characters) and the proportion represented will be rounded to the nearest increment of 1⁄20. For example, given 2016-12-14T12:28
, the progress bar will show Round(28⁄60 × 20) = 9 of 20 units "filled."
1-based months and days
Although the day of December 1 (for example) is 01
in 2016-12-01
, for the purpose of calculation it is the 0th day of the month, because the truncated units imply the 0th millisecond of the 0th minute of the 0th hour of the day. In other words, 2016-12-01
is 0⁄31 of the way through December and 2016-12-02
is 1⁄31, and so on.
Likewise, 2016-01
is the 0th millisecond of the 0th day of January, so in calculations it is 0⁄12, which means 2016-12
is 11⁄12.
Yes, that means months and days will never completely fill the progress bar.
Differing month durations and leap years
Different months have different numbers of days and the output must reflect this—including leap years. The progress bar for February 6, 2017 will be different from the progress bar for February 6, 2016 (or January 6 of both years).
Miscellaneous
- Time travelers use the proleptic Gregorian calendar. TL;DR: No special cases like missing days in 1752. Input will include dates in the year 0 A.D.
- Time travelers ignore daylight savings.
- The program is not required to account for leap seconds, but it may.
Output
The program (or function) must print (or return as a string) a horizontally-oriented 20-character progress bar that is "filled in" for time that has elapsed and "open" for time that remains. It must "fill in" from left to right.
The progress bar must have a label to its left showing the beginning of the period being counted and another to its right showing the beginning of the next period, in the same format as the input (but showing only two units of precision). For our example 2016-12-14
valid output would be:
12-01 #########----------- 01-01
Here are the valid label formats for each of the possible periods:
- Months:
YYYY-MM
- Days:
MM-DD
- Hours:
DDThh
- Minutes:
hh:mm
- Seconds:
mm:ss
- Milliseconds:
ss.sss
No additional units may be included in the labels, and none may be omitted.
Output notes
- The progress bar's "filled in" units will be represented by a
#
character. "Open" units will be represented by-
. - There must be exactly one space between the progress bar and each label.
- Leading or trailing spaces and/or a single trailing newline are allowed.
Winning
This is code-golf. Shortest code in bytes wins. Standard rules apply. Standard loopholes forbidden.
Examples
Input Output
----------------------- -------------------------------------
2016-12-12T12:17 12:00 ######-------------- 13:00
2016-12-12 12-01 #######------------- 01-01
0000-01-01T00:00:00.000 00.000 -------------------- 01.000
0000-01-01T00:00 00:00 -------------------- 01:00
1899-12-31T23 31T00 ###################- 01T00
1899-12-31 12-01 ###################- 01-01
1899-12 1899-01 ##################-- 1900-01
1982-05-15T17:15 17:00 #####--------------- 18:00
1982-05-15T17 15T00 ##############------ 16T00
1982-05 1982-01 #######------------- 1983-01
9999-12-31T23:59:59.999 59.000 #################### 00.000
9999-12 9999-01 ##################-- 10000-01
2000-01-06 01-01 ###----------------- 02-01
2000-02-06 02-01 ###----------------- 03-01
2001-02-06 02-01 ####---------------- 03-01
1742-09-10 09-01 ######-------------- 10-01