4
\$\begingroup\$

Simple question!

Given a string that contains a date in ISO8601 format, print the first of the next month in ISO8601 format.

Example inputs:

2018-05-06

2019-12-20

Their respective outputs:

2018-06-01

2020-01-01

The rules:

  • Imports are free and don't count towards your score.
  • The date will be stored in a string called s.
  • The solution with the least characters, wins
\$\endgroup\$
8
  • 9
    \$\begingroup\$ Please avoid creating new tags unless they're really missing. We already have date and parsing. The beginner tag is an interesting idea, but I think that should be discussed in meta. On the other hand, you must include a tag telling what's the winning criterion. Is this code-golf? \$\endgroup\$
    – Arnauld
    Dec 13, 2019 at 10:27
  • 11
    \$\begingroup\$ I suggest removing The date will be stored in a string called s. and leave it up to the answerers to use any of the default I/O methods. Btw, reading from a pre-defined variable is not among those defaults. Also, not all languages have strings, and not all languages have variables. \$\endgroup\$
    – Adám
    Dec 13, 2019 at 10:31
  • 1
    \$\begingroup\$ Do you mean the output should be stored in s, or that the input would be stored in s? \$\endgroup\$
    – Kobe
    Dec 13, 2019 at 11:00
  • 1
    \$\begingroup\$ @Arnauld There was discussion around that topic (a "beginner" or "easy" tag) quite a while ago with no clear consensus. IMO that's still the case because it's very subjective. \$\endgroup\$ Dec 13, 2019 at 14:40
  • 2
    \$\begingroup\$ I'd say, the newly-added The solution with the least characters, wins could count as the winning criteria, but we prefer not to specify a variable that the input/output have to be stored inside \$\endgroup\$ Dec 20, 2019 at 1:19

7 Answers 7

5
\$\begingroup\$

JavaScript (V8), 67, 57, 56 bytes

-10 thanks to Arnauld,
-1 joining template string and ternary

s=>([a,b]=s.split`-`,+a+!(b%=12))+`-${b++<9?'0'+b:b}-01`

Test cases:

f=s=>([a,b]=s.split`-`,+a+!(b%=12))+`-${b++<9?'0'+b:b}-01`

console.log(f('2018-12-20'))
console.log(f('2019-05-06'))

\$\endgroup\$
5
  • \$\begingroup\$ 57 bytes (without assuming that the input is stored in s, as this unusual requirement will hopefully be removed) \$\endgroup\$
    – Arnauld
    Dec 13, 2019 at 11:12
  • \$\begingroup\$ I never knew you could do that with split, thanks for the input. Might I also ask what's happening with the -~b part? @Arnauld \$\endgroup\$
    – Kobe
    Dec 13, 2019 at 11:25
  • \$\begingroup\$ -~b is -(-b-1) and works on non-numeric values. But since b is already coerced to a number by the modulo, you can actually just use b+1 here. \$\endgroup\$
    – Arnauld
    Dec 13, 2019 at 11:28
  • \$\begingroup\$ @Kobe -~b is basically b+1 (or actually -(-b-1)). It can be useful to skip parenthesis sometimes, although it's not really necessary in this case, so you could change it to b+1 being more readable if you'd prefer. Relevant tip. You might also find Tips for golfing in JavaScript and Tips for golfing in <all languages> interesting to read through. Welcome to CGCC! \$\endgroup\$ Dec 13, 2019 at 11:29
  • \$\begingroup\$ @KevinCruijssen Thanks for the comment and links, I'll definitely take a look at those soon :) \$\endgroup\$
    – Kobe
    Dec 13, 2019 at 11:31
4
\$\begingroup\$

Bash, 31, 24 bytes

7 bytes saved thanks to @manatwork and @nwellnhof

date -d${1%??}1month +%F

Try it online!

\$\endgroup\$
1
  • \$\begingroup\$ Wow! date's parsing ability keeps amazing me. BTW, I think you can skip the “0”. \$\endgroup\$
    – manatwork
    Dec 13, 2019 at 10:57
2
\$\begingroup\$

Ruby 49 bytes

d=Date.parse(s);print Date.new(d.year,d.mon,1)>>1

Online repl

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

Retina 0.8.2, 33 bytes

T`9d`d`.9*(-12)?-..$
-23|-..$
-01

Try it online! Link includes test cases. Explanation:

T`9d`d`

Increment with wrap-around...

.9*(-12)?-..$

... the last non-9 digit, plus trailing 9s, in either the year or the month, depending on whether the month is 12. (Digits in the following date parts also get incremented.)

-23|-..$
-01

Replace the day with 01. Also, if the month was 12 before, it will be 23 now, and also needs to be reset to 01.

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

PHP, 57 bytes

[$y,$m]=explode('-', $s);$m=++$m%13?:!!++$y;$d="$y-$m-1";

Test cases:

<?php
function next_month($s) {
    [$y,$m]=explode('-', $s);
    $m=++$m%13?:!!++$y;
    return "$y-$m-1";
}

$s = "2018-05-06";
echo next_month($s); // Gives 2018-6-1

$s = "2019-12-20";
echo next_month($s); // Gives 2020-1-1
\$\endgroup\$
2
  • \$\begingroup\$ Consider using Try it online! to demonstrate your code. \$\endgroup\$
    – Neil
    Dec 21, 2019 at 20:42
  • \$\begingroup\$ ISO8601 requires Each date and time value has a fixed number of digits that must be padded with leading zeros, meaning output of 2018-6-1 or 2020-1-1 is not valid. \$\endgroup\$
    – 640KB
    Jun 19, 2020 at 1:59
0
\$\begingroup\$

Red, 39 bytes

t: load s
t/month: t/month + t/day: 1
t
\$\endgroup\$
0
\$\begingroup\$

Python 3.6.9, 73 characters

from datetime import *; from dateutil.relativedelta import relativedelta as r; 
(datetime(*map(int, s.split('-')), 1) + r(months=1)).strftime('%Y-%m-01')

Your rules say that imports don't count, so I didn't count them.

\$\endgroup\$
2
  • 2
    \$\begingroup\$ Welcome to Code Golf! Since imports don't count you can from datetime import datetime as d to save a few bytes. Also, you can remove \$\endgroup\$ Jun 20, 2020 at 3:01
  • 1
    \$\begingroup\$ Whoops, accidentally hit enter. Your program does not appear to output anything, so you would need a print statement. To catch this, I suggest using TIO, such as by adding a link: Try It Online!. (I incorporated a couple more suggestions to shorten it to 69 bytes). \$\endgroup\$ Jun 20, 2020 at 3:07

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.

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