all 49 comments

sorted by: hot top controversial new old
[–] 40 points 2 years ago (15 children)

You want to create the date "31st February", but it's JavaScript that's cursed?

Write a less side-effecty function.

function getMonthName(monthNumber) {
    const date = new Date(2023, monthNumber - 1, 1);
    return date.toLocaleString([], { month: 'long' });
}
  • source
  • hideshow 15 child comments
  • [–] [S] 2 points 2 years ago* (last edited 2 years ago) (14 children)

    The point is that this scenario exists in Js in the first place. It's a completely unnecessary rake left around for people to step on. Also, the function isn't side effecty since it doesn't make implicit references outside its scope. The fact that the date is mutable is an internal concern there. You could just as easily do

    function getMonthName(monthNumber) {
      const date = new Date();
      date.setDate(1);  
      date.setMonth(monthNumber - 1);
    
      return date.toLocaleString([], { month: 'long' });
    }
    

    The problem here isn't with side effects, but with having to know that you want to set your date to first day to get the next month reliably.

  • source
  • parent
  • hideshow 14 child comments
  • [–] 13 points 2 years ago* (last edited 2 years ago) (13 children)

    The rake has nothing to do with JS (which I agree is cursed, but for its own reasons, not this).

    You have called a function in a way that does not give a consistent value (Date()). Such functions are hardly the preserve of JavaScript. You've failed to adequately deal with the range of values produced, with code that tries to insist that the "31st February" can be a meaningful date in February. You should accept that this is your mistake and learn to (better) avoid side effects where possible.

    Also, the function isn't side effecty since it doesn't make implicit references outside its scope.

    Edit responding to your edit:

    Also, the function isn't side effecty since it doesn't make implicit references outside its scope.

    The Date() function's output varies according to something other than its input (and even the rest of your program). Using its output without accounting for that variation means that your function, as originally written, also gives inconsistent return values, varying according to something other than its input, because it does, in fact, reference something outside the function. If it did not, the results would only depend on the monthNumber argument, and would always be consistent. I don't know what you call that, but I view it as a side effect.

    As you have said, the rake is that months have different lengths, and you need to account for that. But that's not one of JavaScript's many issues.

  • source
  • parent
  • hideshow 13 child comments
  • [–] [S] -3 points 2 years ago (12 children)

    The idea is to get the current data that will have the current year, month, day in it, and then to query this date for the previous month. A sane API would just throw an error when the date is out of range. A Js API will quitely give you nonsense instead. Again, side effects have absolutely nothing to do with anything here.

  • source
  • parent
  • hideshow 12 child comments
  • [–] 6 points 2 years ago (11 children)

    You've replied while I was editing, so see that regarding what I mean by side effects.

    As far as throwing an error when you try to create "31st February", this wouldn't actually help much, since the error would still only occur on some days of the year, because your original code doesn't account for the range of outputs from Date() when called without arguments.

    To perform correctly, your code needs to normalise the day of the month, or just create the date more explicitly to begin with, but this is a calendrical issue, not a JavaScript one.

  • source
  • parent
  • hideshow 11 child comments
  • [–] [S] -4 points 2 years ago (10 children)

    Side effects are when your function has a reference to some state outside its scope and modifies that state. A function that produces different outputs when it's called, such as getting a current time is not an example of a side effect. Again, the issue here is that Js tries to infer what to do with a bad input, a number outside acceptable range, instead of simply rejecting it.

    My point isn't that you can't write a better function that's less error prone, but the fact that Js allows such things to happen in the first place. It's a very easily avoidable problem at the API level.

  • source
  • parent
  • hideshow 10 child comments
  • [–] 5 points 2 years ago (9 children)

    I was taught that side effects are not so one-sided, and that changing output in response to outside state (such as the date) is also a side effect, a side effect on the function, rather than a side effect of the function, but I'm happy to use other definitions so long as they're commonly understood.

    As I said before, though, even if JavaScript did throw an error as you'd prefer, it would still allow your function to have date-based problems. They'd be a bit noisier perhaps but no less present, and just as "well it's worked fine so far". And that's because, as I keep saying, the real problem here is using a function with inconsistent output and not thoroughly dealing with the possibilities. An API change wouldn't alter that. Most of the time it would still let you write bad code.

    I also probably agree with you that errors are generally better than silence in response to bad input but, as someone else has said (more or less) it's not always unreasonable to consider "31st [Month]" as 31 days after the end of [Previous Month]. Without throwing errors, this flexibility is possible. Perhaps the creators believed having to mutate the day-of-month first was an acceptable trade-off for that.

  • source
  • parent
  • hideshow 9 child comments
  • [–] [S] -3 points 2 years ago (8 children)

    Right, my only point here is that it's better to throw an error when encountering bad or ambiguous input than trying to infer what should happen. I think tha a lot of problems in Js come from it being too accommodating regarding input, and the just trying to figure out what you might've meant. In vast majority of cases, an input of this kind if an indication of an error in the program logic and it's better to fail on such inputs than to accept them. If somebody passes a date that doesn't make sense for a current month, it's almost certainly because they have some logic error in their code. Accepting this date as a parameter simply results in creating a subtle bug in a program that the user likely won't be aware of and that's going to be difficult to find in testing.

  • source
  • parent
  • hideshow 8 child comments
  • [–] 4 points 2 years ago (7 children)

    I agree with you that errors are useful feedback for coders who don't know the ins and outs of an API. And every programmer is in that group at some point. But the difficulty in identifying this particular bug doesn't stem from the API decisions.

    Whether Dates throw an error, or work with what they're given, has no bearing on the subtlety of this bug. Either way, tests that don't replace Date will fail to identify it most of the time, and tests that do, based on its use within the function, would be called wrong-headed by many.

    Either way, the bug only shows up at the end of months longer than the target month, and that infrequency has nothing to do with the peculiar design choices of the Date API. It stems exclusively from the evaluation of Date() called with no arguments returning different values at different times—behaviour you have not objected to, and which I'd expect to be considered entirely appropriate, in fact its very point—combined with an attempt to use that value, whatever it may be, without due consideration.

    Since the month is the only part of interest, there's no reason to allow the other parts to vary at all. Fixing them, as I suggested at the beginning of all this, is the simplest approach, but setting them first, as has also been suggested, would work too.

    You can once again complain about JS design decisions and I'll agree about many of them, but, as much as you might like it to be, and as annoying as so many of us think they often are, here it is beside the point. The perniciousness of this particular bug stems from unnecessarily calling a function with inconsistent output and then improperly processing that, instead of using a function call with always-predictable output.

    I've tried to point that out in all the ways I can think of, so if it's still not getting through, I give up. And if your acknowledgement was too subtle for my sleepy brain, and I've ended up overexplaining, then I'm sorry.

  • source
  • parent
  • hideshow 7 child comments
  • [–] [S] -3 points 2 years ago* (last edited 2 years ago) (6 children)

    The difference is that hrowing an error makes it much easier to find the bug early, while doing the wrong thing silently makes it much harder to do so. If an error is thrown by the API then the first time wrong input is supply the application will fail and you'll know you have a problem. If the API silently does the wrong thing, then the application will keep doing the wrong thing until somebody notices and that tends to be far more costly.

    Finally, I'd like to note that this isn't a hypothetical debate. This is how APIs work in sane languages such as Java:

    java.time.LocalDate.of(2023, 2, 31)
    > java.time.DateTimeException: Invalid date 'FEBRUARY 31'
    
    java.time.LocalDate.of(2023, 2, 3)
    > #object[java.time.LocalDate 0x2bc77260 "2023-02-03"]
    
  • source
  • parent
  • hideshow 6 child comments
  • [–] 5 points 2 years ago (5 children)

    Yes, and I've said that I agree with that in general. I know that this isn't hypothetical; that's exactly why I keep saying that throwing an error doesn't help you find this bug early at all.

    Even the silent weirdness can be caught by the most basic of tests checking output against input, but only if your function works the same way on every invocation.

    Whether making a giant fuss (as you'd prefer) or making the best of it (as it actually does), the setMonth method always works the same way. My code always works the same way. The setDate suggestion makes the code always work the same way.

    Code that always works the same way is easy to test.

    If the day of the month is constant and incompatible with setMonth, whether there's a thrown error or just an unwanted return value, a simple test will reveal that on every test run. If the day of the month is constant and always compatible with setMonth, the test will pass appropriately on every test run.

    The bug in the code you originally presented comes from working differently over time. That's why, most days, tests won't identify the problem, even with a fussy, noisy API. Most testing days, the date will just happen to be compatible, and even the fussiest, noisiest API will carry on without any mention of the problem.

    The reason the original code works differently over time has nothing to do with the silent, unexpected behaviour of setMonth. It's entirely down to calling Date() without arguments, the entire point of which is to give different values over time. That call effectively introduces state that is not controlled by the function. And not bringing it under control is the real source of the bug.

    Yes, absolutely, JavaScript sucks. Make F# the only supported web scripting language! But JavaScript's suckiness is not the cause of this particular bug. JavaScript's suckiness is not the reason this bug is hard to catch. The real problem lies in code that functions differently over time when it should (and could easily) be consistent. That's what actually makes it hard to test.

    Plenty of other languages and API design choices still allow code that functions that work differently over time, which is why, as justifiable as the complaints are in general, those factors are irrelevant for this particular bug. Write code that always works the same way and the problem goes away. That's the real core of the issue.

    Obviously, that's easier said than done, and it's irritating that neither loud errors nor most testing will help you in this regard, but that's the way it is.

  • source
  • parent
  • hideshow 5 child comments
  • [–] [S] -4 points 2 years ago (4 children)

    Whether making a giant fuss (as you’d prefer) or making the best of it (as it actually does), the setMonth method always works the same way. My code always works the same way. The setDate suggestion makes the code always work the same way.

    You're missing my point entirely here. Current behavior works in a SURPRISING way and SILENTLY produces an output that's most likely to be unintended. Let me give you a concrete example of the problem here.

    Let's say you have a calendar app that shows the current day by default, and then there are buttons to go to next or previous month. To get the current day you'd have to call Date(), and then you'd have next and previous month functions that would work off the date you got. In Js world these functions will mostly work, but once in a while give users a wrong month silently.

    The bug in the code you originally presented comes from working differently over time. That’s why, most days, tests won’t identify the problem, even with a fussy, noisy API. Most testing days, the date will just happen to be compatible, and even the fussiest, noisiest API will carry on without any mention of the problem.

    That's not the problem at all, and your whole line of argument here is frankly bizarre. There are plenty of use cases where you need to have functions that do something based on a current date. That means needing to get the date from the system without knowing what that date is up front by calling Date() without set arguments. This isn't some anti pattern that you keep trying to make it out to be. There is absolutely nothing wrong with getting the current date.

  • source
  • parent
  • hideshow 4 child comments
  • [–] 4 points 2 years ago (3 children)

    I'm not missing your points, even as you change them. I've agreed that JS sucks. I've agreed that errors can be more helpful. I'm not trying to argue with you about that. What I have said, from the beginning, is that in the code you originally presented a behavioural change for setMonth will not help you find the problem any faster. Test failures for the wrong output occur just as often as test failures for errors, on exactly the same few days each year. The API change gives no advantage for the specific function this discussion started with in this regard. However, an approach that avoids inconsistency will, because in this particular instance, that is the real source of the problem. That is all.

    In that context—the one you started with—it does not matter that there is often good reason to call Date() without arguments. The getMonthName function presented, effectively an array lookup, should produce the same output for any given input every time. It has no reason to engage in any behaviour that varies from day to day.

    There is absolutely nothing wrong with getting the current date.

    Bluntly, the code you presented fails precisely because it gets the current date where it should create a more specific one, and then fails to deal with that variation appropriately. You can keep distracting yourself with language design decisions, but that won't help you avoid this particular type of problem in the future because that's not where it is.

    Getting the current date is often fine. In this specific instance, it is not. That is why the function doesn't work. If you are missing that point, as much as I appreciate your enthusiasm in continuing the conversation, I will take the L (and the code that actually works) and move on.

  • source
  • parent
  • hideshow 3 child comments
  • [–] [S] -5 points 2 years ago (2 children)

    What points have I changed, please be sepcific.

    What I have said, from the beginning, is that in the code you originally presented a behavioural change for setMonth will not help you find the problem any faster.

    Yes, it would help find the problem faster because the first time invalid date is passed in the program will crash. The current behavior means the program will keep running and the only time it will become apparent that there is an error is when somebody notices that the month is wrong. You keep saying you're not missing my points, but here we are.

    In that context—the one you started with—it does not matter that there is often good reason to call Date() without arguments. The getMonthName function presented, effectively an array lookup, should produce the same output for any given input every time. It has no reason to engage in any behaviour that varies from day to day.

    Again, the point that was actually being made is that this whole scenario can be avoided by rejecting invalid inputs for the date of the month.

    Bluntly, the code you presented fails precisely because it gets the current date where it should create a more specific one, and then fails to deal with that variation appropriately.

    Bluntly, I've already explained to you that the code presented is not the problem and is a valid use case.

    Getting the current date is often fine. In this specific instance, it is not.

    This specific instance is a legitimate use case for getting the current date because the intent of the code is to get the previous month RELATIVE to the current date. The code you provide simply hacks around this problem by hard coding the date.

  • source
  • parent
  • hideshow 2 child comments
  • [–] 5 points 2 years ago (1 child)

    the intent of the code is to get the previous month RELATIVE to the current date.

    But that isn't what it does. From the original post:

    function getMonthName(monthNumber) {
      const date = new Date();
      date.setMonth(monthNumber - 1);
    
      return date.toLocaleString([], { month: 'long' });
    }
    

    That is a function which is meant to take a number (presumably 1 to 12) and return a localized name for it. This is essentially an array lookup and should return the same output for a given input (and locale) every time it is called. If the intent is to return a value relative to the current date, it is even more wrong, since it should gather the month from the current date, not the function paramenter. This claim of intent, not present in the original post, is an example of you changing your story over time.

    Yes, it would help find the problem faster because the first time invalid date is passed in the program will crash.

    No, it wouldn't. As I have said before, testing for unexpected return values is just as effective as testing for errors, that is, not very with the function originally presented under sensible assumptions. If the function actually did look like the intent you claim, the tests would be different, necessarily replacing Date for consistent runs, but would be equally likely to catch the problem whether failing on value or error. And if you are eschewing testing and relying on runtime crashes, you have bigger problems.

    Given that I have agreed and commiserated, and neither of us can change JavaScript, there is nothing to be gained from pursuing this complaint. In contrast, what I have tried to say, if followed, would give you an approach that leads to more reliable code, even in the face of undesirable APIs.

    I had thought that worth pursuing, and had thought you worth investing my considerable time. Alas, I can only lead you to the water...

  • source
  • parent
  • hideshow 1 child comment
  • [–] [S] -5 points 2 years ago

    But that isn’t what it does. From the original post:

    The problem would be the same if you were just doing an offset from the current month. You're now nitpicking the example while ignoring the point being made. Perhaps this version will help clarify the problem for you better:

    function getLastMonthName() {
      const date = new Date();
      date.setMonth(date.getMonth() - 1);
      return date.toLocaleString([], { month: 'long' });
    }
    

    No, it wouldn’t. As I have said before, testing for unexpected return values is just as effective as testing for errors, that is, not very with the function originally presented under sensible assumptions.

    I'll repeat this again, the failure case is not obvious and you can easily miss the test for it. Throwing an error makes it much easier to identify that there is a problem, and that's why APIs in sane languages such as Java behave this way.

    This claim of intent, not present in the original post, is an example of you changing your story over time.

    Nobody is changing the story over time, you're just incapable of acknowledging being wrong.

    Given that I have agreed and commiserated, and neither of us can change JavaScript, there is nothing to be gained from pursuing this complaint.

    Which is precisely why I posted this on Programmer Humor. Js is a garbage language, and it's obviously beyond fixing, but I can laugh at it.

  • source
  • parent
  • [–] 21 points 2 years ago

    The legacy Date object has many problems and this is one of them. Another infamous one is that it uses zero-based month numbers: January is the zeroth month and December the 11th month.

    This will be fixed Any Day Now™️ when Temporal is released. This is a carefully designed library that supersedes Date and is currently waiting on some standards to be finalized.

  • source
  • [–] 9 points 2 years ago* (22 children)

    date.setDate(1);

    Problem solved.

  • source
  • hideshow 22 child comments
  • [–] [S] 0 points 2 years ago (21 children)

    Sure, but the question is why anybody thought this would be a desirable behavior in the first place.

  • source
  • parent
  • hideshow 21 child comments
  • [–] 17 points 2 years ago (16 children)

    It's because there's no right answer, and this way gets you the intuitive answer most often.

    A month isn't a proper unit of time. Adding a month to a date can't be done without specifying which month you're adding.

    You could argue that one month from January 31 is February 28, 29 (depending on the year), March 2, or 3.

    Should one month from the last day be the last day of the next month? That would mean that the 30th and the 31st of march are both the same duration from April 30th, and a month before April 30th could logically map to either one.

    So they chose the path that, for anything other than the 31st, and the 29th and 30th if it comes near February, works as you expect. "A month after 17 days from the first of January is 17 days after the first of february.”

    The other alternatives involve not allowing the addition and subtraction of irregular time intervals, but then you get frustrated that you can only deal with seconds, since those don't change in length.

  • source
  • parent
  • hideshow 16 child comments
  • [+] [S] -8 points 2 years ago (15 children)

    Having restrictions is far better than having random pitfalls that you fall into. An API works as you'd expect majority of the time and then has an edge case that's entirely not obvious is a bad API. The whole problem with Js is that it's full of rakes that you can step on. You can rationalize every one of these weird behaviors in Js, but that doesn't make the language any easier to work with in practice. People forget a random rule here or there and then their code breaks in weird ways when the stars align just right. This is simply not how APIs should be designed.

  • source
  • parent
  • hideshow 15 child comments
  • [–] 3 points 2 years ago (9 children)

    In this case though, it's consistent, and is just one of the annoying ways the problem could be solved. Datetime math is just fucked up.

    You can just not support that functionality, which gives you people making their own mistakes and forgetting leap years or hard coding all sorts of insanity.

    You can clamp the value to the end of the month, but that gives you the odd case where date + month - month != date in some days, which is also a weird pitfall.

    If I see any code dealing with adding and subtracting months, I'm either checking the manual or I already know it's behavior from doing so before.
    I'm all about not liking how JS does stuff, but Datetime math is the one area where in willing to forgive most insanity of outcomes.

  • source
  • parent
  • hideshow 9 child comments
  • [+] [S] -8 points 2 years ago (8 children)

    One way to solve the problem is to give an error when you end up with an invalid input such as a data outside the range of valid dates for the month. The other way to solve the problem is to silently return nonsense which is what Js does. It's just a matter of doing basic input validation.

  • source
  • parent
  • hideshow 8 child comments
  • [–] 2 points 2 years ago (7 children)

    Except it's not nonsense. If you ask for 31 days after January 31st, you don't get February 28th.

    A month is a malformed concept to use in conjunction with arithmetic, except for the part where people do it all the time and just ignore the fact that it often gets weird.

    Do you really think you'd be happier if the answer for "what's a month from 01/31?” was "InvalidDateException"? That every other month the concept of "a month from today" is just undefined?

    Saying "adding a month means adding the number of days in the starting month" is one choice of many, all of which have terrible downsides.

  • source
  • parent
  • hideshow 7 child comments
  • [+] [S] -8 points 2 years ago (6 children)

    Are you seriously arguing that this is the behavior a person using this API would intuitively expect?

  • source
  • parent
  • hideshow 6 child comments
  • [–] 2 points 2 years ago (5 children)

    What behavior do you expect? Specifically.

    I'm arguing that every answer is wrong, and will return bizarre results, be aggravating, useless or some combination therein for some conditions.
    Therefore you have to know the API, because every language will fuck you, and JavaScript isn't special in this specific case.

    Adding the number of days in the month to the date as "add one month" is just as rational as any other choice.

  • source
  • parent
  • hideshow 5 child comments
  • [+] [S] -8 points 2 years ago (4 children)

    The behavior I would expect would be to throw an error when the date is outside of the range of valid dates for the month. If you try to create a date on February 31st throw an error. Have you seriously never used a good API that's intuitive and isn't full of gotchas?

  • source
  • parent
  • hideshow 4 child comments
  • [–] 1 point 2 years ago (3 children)

    Have you never done Datetime math before?

    You didn't run new Date(2019, 02, 31), you asked it for one month from January 31st.
    One month after any given day of the month is, by most people's intuition, a valid thing to ask for.

    Your solution of making the API throw an exception for every 31st of the year is vastly less intuitive to me than "a month is 31 days in January, and 28 or 29 in February, so adding a month does different things in different months", because at least for those is can also query how many days are in the month.

    If I say to add four days, will it throw an exception if it's the 31st? No month has 35 days, so I should get an exception, right?
    Or is it just this weird caveat around months? Does it apply to time?

  • source
  • parent
  • hideshow 3 child comments
  • [+] [S] -6 points 2 years ago* (last edited 2 years ago) (2 children)

    One month after any given day of the month is, by most people’s intuition, a valid thing to ask for.

    Nobody actually thinks this way, when you ask somebody what's the next month they don't go, oh today is the x day of the month and I'm going to add days to the current date to see what's the next month. That's not how vast majority of people think about this intuitively. Clearly you and people who designed Js Date API do though.

    “a month is 31 days in January, and 28 or 29 in February, so adding a month does different things in different months”

    That's how months work. Each month has a different number of days.

    If I say to add four days, will it throw an exception if it’s the 31st? No month has 35 days, so I should get an exception, right?

    Yeah, it's how months work.

    In fact, this isn't a hypothetical argument this is how date APIs work in sane languages like Java. For example:

    java.time.LocalDate.of(2023, 2, 31)
    > java.time.DateTimeException: Invalid date 'FEBRUARY 31'
    
    java.time.LocalDate.of(2023, 2, 3)
    > #object[java.time.LocalDate 0x2bc77260 "2023-02-03"]
    

    The fact that you think what Js API dies is preferable to this is frankly surreal to me.

  • source
  • parent
  • hideshow 2 child comments
  • [–] 1 point 2 years ago (1 child)

    So, you're talking about throwing exceptions if adding a month yields an invalid date if done without nuance, but then you're showing an example of just trying to instantiate an invalid date in java.

    I believe java has an addMonths method, that in the situation we're talking about doesn't throw an exception, but rather limits the output to the 28th/ 29th/30th.

    Which illustrates my point: intuitive Datetime math involves choosing how you handle edge cases that are routine and not exceptional, like "a month from January 31st".

    The rest of your comment arguing about how people expect months to work just makes me feel like you've never actually talked to a business stakeholder about requirements.

    If I say to add four days, will it throw an exception if it’s the 31st? No month has 35 days, so I should get an exception, right?

    Yeah, it's how months work.

    That's just insane. An API that doesn't increment the month when you pass the end while adding days is just broken.

  • source
  • parent
  • hideshow 1 child comment
  • [+] [S] -7 points 2 years ago

    I encourage you to actually try using Java API to see how it works if you don't think my example is illustrative enough. Meanwhile, the only insane thing here is you thinking that how an API works has anything to do with business stakeholders and requirements. This statement clearly illustrates that you don't understand how to translate business requirements into code and perhaps should spend some time learning how to do that instead of trolling here.

  • source
  • parent
  • [+] 2 points 2 years ago* (last edited 2 years ago) (4 children)
  • [–] 1 point 2 years ago (2 children)

    So, the flip side to that is that sometimes you need to add one month to a date, because that sometimes how human systems are written.
    By not providing a function that does that, you're just pushing the confusion down to the developer, who is more likely to make terrible errors in the process, get frustrated, or use one of N different competing libraries, each of which chose a different answer.

    Omitting functionality that can behave unintuitively in certain circumstances means leaving out a lot of functionality that people need.

    Like, "decimal numbers" go pathological in certain cases. So do Unicode characters. Don't even bother thinking about connecting to the network.

  • source
  • parent
  • hideshow 2 child comments
  • [+] 0 points 2 years ago* (last edited 2 years ago) (1 child)
  • [–] [S] -5 points 2 years ago

    Exactly, it's better to not have these sorts of "conveniences" than to create weird pitfalls. I find a lot of crazy Js behaviors are ultimately a result of Js trying to be accommodating of inputs that should just be straight up rejected.

  • source
  • parent
  • [–] 4 points 2 years ago (3 children)

    I love js. But the date object has always been a total pain. Moment.js is a good package to deal with it, but yeah, it's currently deprecated, but it would be nice if it or something like it became part of ECMAScript.

    I have no idea why it hasn't yet, except that it might be that js needs to work for everyone, not just the us. So time is not standard.

  • source
  • parent
  • hideshow 3 child comments
  • [–] 3 points 2 years ago* (1 child)

    The date API is like the original rip of the Java date API. Barely changed, and totally backwards compatible nonsense.

    Temporal is the new JavaScript/ECMAScript date API.
    It's stage 3, and likely stable (just a few kinks being worked out). So you could polyfill it for production.
    https://github.com/tc39/proposal-temporal

  • source
  • parent
  • hideshow 1 child comment
  • [–] 1 point 2 years ago

    Speaking of Java RipS. How annoying is it the JS has left Java in the dust as far as looser standards?

    Developing in Java: YOU FORGOT A SEMI-COLON ARE YOU CRAZY?! HOW IS THE COMPILER SUPPOSED TO KNOW WHAT TO DO?!

    Developing in JS: Who gives a fuck about semi-colons?

  • source
  • parent
  • [–] 6 points 2 years ago

    Oh, because if the month you chose has less than 31 days, it'll assume the 31st of September is the 1st of October? That's reasonable.

  • source
  • [–] 3 points 2 years ago (1 child)

    Somebody has not worked with dates for very long, to be so sure of themselves...

  • source
  • hideshow 1 child comment
  • [–] 2 points 2 years ago (5 children)

    The amount of people arguing that this is a fine behavior in this thread makes the whole thing even funnier.

  • source
  • hideshow 5 child comments
  • [–] 3 points 2 years ago (2 children)

    What would you expect "-1 month" to do for a date like 31st of March? Would the result be the same as for "-1 month" on 29th of March?

    If you go back 2 months so the 31st is existing again - should that mean that the result of using -1 month twice should be different to using -2 months?

    I think it's just a stupid way to implement something like this as "month" isn't a defined size so defining it with a fixed value and documenting it properly is a decent solution but noone should use that kind of function in the first place

  • source
  • parent
  • hideshow 2 child comments
  • [–] 4 points 2 years ago*

    It is a stupid way to implement it, but the called function is named setMonth()! The minus one is performed externally, so if you set February you expect February, validation should adjust the other fields...

  • source
  • parent
  • [–] 4 points 2 years ago

    This is literally how every sane API works in languages built by adults. For example, here's what happens in Java:

    java.time.LocalDate.of(2023, 3, 31)
    > #object[java.time.LocalDate 0x2bc77260 "2023-03-31"]
    java.time.LocalDate.of(2023, 3, 31).minusMonths(1)
    > #object[java.time.LocalDate 0xac0dc15 "2023-02-28"]
    java.time.LocalDate.of(2023, 3, 31).minusMonths(2)
    > #object[java.time.LocalDate 0x44b9305f "2023-01-31"]
    

    I have no idea where people get this notion that a month isn't a defined size. Do people just not understand the concept of a month?

  • source
  • parent