12
\$\begingroup\$

Input a datetime, format the datetime in YYYY-MM-DD HH:mm:ss format using 30-hour clock time.

The 30-hour clock time works as:

  • After 6 a.m., it is same as 24-hour clock time
  • Before 6 a.m., it use date for previous day, and plus Hours by 24.

For more examples, you may checkout the testcases.

Rules

  • To simplify the question
    • You may choose to use client timezone or UTC timezone by your prefer;
    • You may assume the client timezone don't have DST;
    • You may assume no leap second.
  • This is code-golf.
  • Input can be in any convenience format. Although certainly, you cannot take input in 30-hour clock time.
  • Output need to be a string, displayed on screen, or other similar replacements with exactly specified format.

Testcases

Input               -> Output
2023-12-01 00:00:00 -> 2023-11-30 24:00:00
2023-12-01 01:23:45 -> 2023-11-30 25:23:45
2023-12-01 05:59:59 -> 2023-11-30 29:59:59
2023-12-01 06:00:00 -> 2023-12-01 06:00:00 or 2023-11-30 30:00:00
2023-12-01 06:00:01 -> 2023-12-01 06:00:01
2023-12-01 12:34:56 -> 2023-12-01 12:34:56
2023-12-01 23:59:59 -> 2023-12-01 23:59:59
2024-01-01 02:00:00 -> 2023-12-31 26:00:00
2024-03-01 00:00:00 -> 2024-02-29 24:00:00
\$\endgroup\$

10 Answers 10

6
\$\begingroup\$

Ruby, 62 56 48 bytes

->d{r="#{d-21600}"[0,19];60000.times{r.succ!};r}

Try it online!

\$\endgroup\$
1
  • \$\begingroup\$ 44 bytes \$\endgroup\$
    – Dingus
    Dec 21, 2023 at 13:31
3
\$\begingroup\$

Excel ms365, 71 bytes

Assuming input as normal date-time value in A1:

=LET(x,MOD(A1,1),y,x<0.25,TEXT(A1-y,"e-mm-dd ")&TEXT(x+y,"[hh]:mm:ss"))
\$\endgroup\$
3
\$\begingroup\$

Bash, 81, 89, 86 bytes

h=$[24+10#${1:11:2}];r=`date -d$1-$[h<30]day +%F\ %T`;((h<30))&&r=${r/ ??/ $h};echo $r

Try it online!

Perl 5 -MPOSIX=strftime -p, 99 bytes

@a=reverse/\d+/g;$a[5]-=1900;--$a[4];$h=$a[2]+24;--$a[3];$_=strftime("%F %T",@a),s/ ../ $h/ if$h<30

Try it online!

\$\endgroup\$
2
  • \$\begingroup\$ This question is asking about format the time in specified format. Although input format is flexible, output is required to be exactly specified string format. The required format does not include +00:00 part nor T letter in your output. \$\endgroup\$
    – tsh
    Dec 21, 2023 at 11:00
  • \$\begingroup\$ @tsh, done +8 bytes \$\endgroup\$ Dec 21, 2023 at 11:45
2
\$\begingroup\$

Factor, 78 bytes

[ dup hour>> 6 < [ 1 days time- [ 24 + ] change-hour ] when timestamp>ymdhms ]

Attempt This Online!

Takes a timestamp object (in 24-hour time); returns a string.

  • dup hour>> 6 < is the hour less than six?
  • [ ... ] when then do ...
  • 1 days time- subtract one day
  • [ 24 + ] change-hour add twenty-four hours in a way that doesn't roll the day over
  • timestamp>ymdhms change the timestamp to a string in the required format
\$\endgroup\$
2
\$\begingroup\$

APL (Dyalog APL), 55 bytes

Anonymous prefix lambda, taking a Dyalog Date Number (number of days since the beginning of 1899-12-31) as argument.

{' 1'⎕R' 2'⍣a⊢'T'⎕R' '⊃'%ISO%'(1200⌶)⍵-12÷⍨5×a←1>4×1|⍵}

Attempt This Online!

{} "dfn"; argument is :

 the argument

1| remainder when the divided by 1 (i.e. the fractional part)

 four times that

1> is 1 greater than that? (i.e. is the time part of the argument before 06:00?)

a← store this in a (for adjust)

 five times that

12÷⍨ that divided by twelve (this gives the number of days to subtract corresponding to subtracting ten hours)

'%ISO%'(1200⌶) represent the Dyalog Date Number as an array of ISO 8601 extended format strings (YYYY-MM-DD"T"hh:mm:ss)

 get the first element of that (since we returned an array of strings)

'T'⎕R' 'Replace the letter "T" with a space (since the ISO format separates date and time with a "T")

 …⍣a⊢ if we need to adjust (a):

  ' 1'⎕R' 2'Replace " 1" with " 2" (to add back the missing 10 hours)

\$\endgroup\$
2
\$\begingroup\$

Bash + common linux utils, 66

date "-d$1+6" '+%F %H %M:%S'|awk '{printf"%s %02d:%s",$1,$2+6,$3}'

Try it online!

\$\endgroup\$
2
\$\begingroup\$

JavaScript (Node.js), 69 bytes

x=>x.toJSON().replace(/T(..)|\..*/g,(_,x)=>' '+(-x-1006+'').slice(3))

Try it online!

Only work in GMT+6

JavaScript (Node.js), 84 bytes

x=>new Date(x+'+6').toJSON().replace(/T(..)|\..*/g,(_,x)=>' '+(-x-1006+'').slice(3))

Try it online!

Set GMT+6 in code so work everywhere

\$\endgroup\$
4
  • \$\begingroup\$ Can you post the UTC solution? The question asks that you only use UTC or client. Let me know if I'm misunderstanding. \$\endgroup\$
    – Tbw
    Dec 21, 2023 at 7:48
  • \$\begingroup\$ @Tbw If you mean it suggest UTC rather than GMT, then they only differ leap second which is ignored. If you mean allow GMT+0 then it's now linked \$\endgroup\$
    – l4m2
    Dec 21, 2023 at 7:55
  • 2
    \$\begingroup\$ The question requires using user's timezone or UTC (GMT). So only support GMT+6 won't fit the requirement. So maybe your 85 bytes version should be fine. \$\endgroup\$
    – tsh
    Dec 21, 2023 at 10:58
  • \$\begingroup\$ @tsh It's about running environment requirement, but I can't find such on meta \$\endgroup\$
    – l4m2
    Dec 21, 2023 at 11:40
2
\$\begingroup\$

Retina 0.8.2, 149 142 bytes

T`d`4-9` 0[0-5]
T`d`9d`.0?(-01)* 4
 3
 2
-90-
-12-
((?!00)([02468][048]|[13579][26])(00)?-02)-90
$1-29
02-90
02-28
(0[^469]|10|12)?-90
$1-3$#1

Try it online! Link includes test cases. Explanation:

T`d`4-9` 0[0-5]

Add 44 hours to times between midnight and 6am.

T`d`9d`.0?(-01)* 4

Subtract 1 day and 10 hours from those times, plus also subtract 1 month and 1 year if the day (and month) were originally 1; in this case the day (and month) "rolls under" to 90 and will be fixed up later to the correct last day or month.

 3
 2

Subtract another 10 hours from those times.

-90-
-12-

Change month 90 to December.

((?!00)([02468][048]|[13579][26])(00)?-02)-90
$1-29

February in a leap year has 29 days.

02-99
02-28

Other Feburaries have 28 days. (This must be February rather than, say, 2002, because month 90 was fixed up earlier.)

(0[^469]|10|12)?-90
$1-3$#1

Fix up the last day of the month in other months.

\$\endgroup\$
1
\$\begingroup\$

Jelly, 75 bytes

ọ4,25>/“ḢȷĠ’b4¤o+28ṙḢ;@,’ḅ’dɗ12‘ʋ
Ṗç/$’3¦ỊṪ$?,+1¦24$}ɗ,<6Ḣ$}?Ṿ¹ŻṖ?$€€j"⁾-:K

A full program taking the Y,M,D year as a list of three integers as the first argument and the H,M,S time as a list of three integers as the second argument. Prints a formatted string as a 30-hour time. Most of the code reflects Jelly’s lack of date time handling.

\$\endgroup\$
2
  • \$\begingroup\$ This question is asking about format the time in specified format. Output is required to be exactly specified string format, not a tuple of 6 values. \$\endgroup\$
    – tsh
    Dec 21, 2023 at 10:49
  • \$\begingroup\$ @tsh apologies I thought both input and output formats were flexible. I’ve preserved the same input format but now outputting as a string. Hope that’s ok \$\endgroup\$ Dec 21, 2023 at 14:37
1
\$\begingroup\$

Charcoal, 97 87 bytes

¿‹η06«≔I⪪θ-υ⪫﹪%02dEυ∨⁻ι¬⊙υ∧›μκ⊖λ⎇⊖κ⁺²⁸∨I§”)“∧Bn»”§υ¹¬﹪⊟Φ↨§υ⁰¦¹⁰⁰μ⁴¦¹²-⁺ ⁺²⁴I…η²✂η²»«θ η

Try it online! Link is to verbose version of code. Takes input as separate "words", i.e. the date and time can be on two lines instead of space-separated. Explanation:

¿‹η06«

If the time is before 6am, then:

≔I⪪θ-υ

Split the date on - and cast to integer.

⪫﹪%02dEυ∨⁻ι¬⊙υ∧›μκ⊖λ⎇⊖κ⁺²⁸∨I§”)“∧Bn»”§υ¹¬﹪⊟Φ↨§υ⁰¦¹⁰⁰μ⁴¦¹²-

Decrement any component where all the following components are all 1, but if the component becomes zero, then replace it with 12 if it's the month otherwise calculate the number of days in the previous month. Format and output the resulting date.

⁺ ⁺²⁴I…η²

Add 24 to the hours.

✂η²

Output the minutes and seconds.

»«θ η

Otherwise just output the date and time.

\$\endgroup\$

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.