-
Notifications
You must be signed in to change notification settings - Fork 153
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Reconsider allowing strings in withDate() and withTime()? #592
Comments
I think TimeZones are a bit special, in terms of being treated as strings (e.g., in Intl), as well as not having any numbers/user data in them in the default case. I've previously argued that we should be restrictive in terms of where we include "coercion" logic. I think it can get confusing if we allow lots of coercion by default in these argument positions, and that it's better to be explicit. I'm wondering, do you want options bags to be accepted in these positions too, as we previously did, before restricting coercion? |
To be honest, I hadn't thought about the options bags, mainly because I wasn't using them in my (limited) experiments. I don't see a problem with accepting them, because then it becomes easier to explain as a concept — e.g. "the argument passed to Note: I'm saying this purely from the point of view of an API consumer, not a spec writer. It's entirely possible there's a problematic case I've missed. |
Strings are problematic when it comes to calendar systems, since they are unlikely to carry calendar annotations (#293). It is better to explicitly transition from strings into Temporal objects, rather than doing so implicitly in methods like Temporal.Time.prototype.withDate(). |
I see that, but I don't necessarily agree that's a concern in the particular case of withTime and withDate. If you have |
Also, if a string is rejected, the user's just going to make an object from the string and pass it in anyways, which doesn't provide any additional information. |
I support accepting strings here, both for ergonomics and for consistency with timezone or calendar parameters. I don't think we should accept options bags in this position, because it makes for a confusing IDE autocomplete UX. Better to require |
Note for context: After this issue was created, the method names were changed from
@justingrant You've put forward the "IDE autocomplete experience" argument in a lot of cases around the API design. For the most part, I agree that we should make things easier for that scenario, and there are some nice discoverability tricks. (Your argument for However, in this case I disagree with the argument. IDE autocomplete experience is a good consideration, but should not be an overriding principle, especially when it decreases consistency in APIs.
|
@gilmoreorless - I'm not sure I understand our disagreement here, could you explain? Are we actually agreeing? My point was only about options bags as related to @littledan's comment :
The specific case I think should be disallowed is where the same argument position can either be a Temporal-like object literal like
Agreed. We don't allow options bags in the first position of I also agree that
I also agree here. IDE experience shouldn't be paramount-- it's just one consideration among many. OK, where do we disagree? ;-) |
Errrgh, I think this mess has come about due to my misreading of one key word. When @littledan asked about options bags, I was interpreting that as meaning property bags. 🤦 So, to clarify:
Sorry for all the confusion. 😄 |
@gilmoreorless No worries, after I posted my questions above it occurred to me that you might have misread that word. All's good. Do you want to revise your OP to include both strings and object property (not options!) bags in the proposal? The general pattern here seems to be a good one if a conversion method requires additional data, then its argument should mirror This is also relevant to the discussion we're having over in #747 about conversion methods overall. Question for you: how do you think the proposed EDIT: added non-optional calendar per @sffc's latest proposal, and added Option 4 per @gibson042 suggestion in #592 (comment). // Option 1: separate arguments
date.toLocalDateTime('America/Los_Angeles', '12:00');
date.toLocalDateTime('America/Los_Angeles'); // defaults to first moment of this day, usually but not always midnight
// Option 2: one argument: property bag with required `timeZone` property and optional `time` property
date.toLocalDateTime({timeZone: 'America/Los_Angeles', time: '12:00'});
date.toLocalDateTime({timeZone: 'America/Los_Angeles'}); // start of day, usually midnight
// Option 3: one bag with spread properties
date.toLocalDateTime({timeZone: 'America/Los_Angeles', ...Temporal.Time.from('12:00').getFields()});
date.toLocalDateTime({timeZone: 'America/Los_Angeles'}); // start of day, usually midnight
// Option 4: no conversion methods that always require multiple inputs
date.toDateTime('12:00').toLocalDateTime('America/Los_Angeles');
date.toDateTime().toLocalDateTime('America/Los_Angeles'); // start of day, usually midnight Each of these options has pros and cons. Option 1 is briefest and probably the most ergonomic, but it's not necessarily obvious from the API shape whether the timezone or the time should go first. This ambiguity might lead to occasional reversal bugs. Option 2 has no ambiguity, but a Option 3 is, honestly, not a significant ergonomic benefit because you can't use a string for the time. It'd be easier for the caller to do this instead: date.toDateTime('12:00').toLocalDateTime('America/Los_Angeles'); I'm not a fan of Option 4:
I'd lean towards Option 2 if we could resurrect #720 and resolve the problems with it. Otherwise Option 1. EDIT: one thing to keep in mind when choosing between the options above is how we'd handle EDIT: another thing to consider: |
// Option 4: no conversion methods that always require multiple inputs
date.toDateTime('12:00').toLocalDateTime('America/Los_Angeles'); |
Yep agreed, that's another option to consider. I added it to #592 (comment) above to keep all the options in one place. I also added a variant showing how it looks when the time is set to the start-of-day default. |
BTW, |
Done.
My preference is Option 1 (followed by Option 2, but you're right that it causes other problems). I don't actually see the accidental reversal of arguments in Option 1 as being a big problem. Mainly because the types of arguments are different enough that reversing their order will cause parsing exceptions straight away. Though there is one case I can think of with ambiguity, when date.toLocalDateTime('+10:00', '10:00') // Not identical arguments, but close enough to be confusing |
FYI I just updated #720 which may resolve the problems with Option 2. |
Decision 2020-09-11:
|
Strings are allowed in the methods that have a Temporal.Instant argument, and both strings and property bags are allowed in the methods that have a Temporal.DateTime argument. See: #592
These operations will be used elsewhere to convert arguments to other methods, so change them into abstract operations. See: #592
Property bags were already allowed. See: #592
Also in toZonedDateTime() methods in the documentation, but those are not implemented yet. See: #592
Strings are allowed in the methods that have a Temporal.Instant argument, and both strings and property bags are allowed in the methods that have a Temporal.DateTime argument. See: #592
These operations will be used elsewhere to convert arguments to other methods, so change them into abstract operations. See: #592
Property bags were already allowed. See: #592
Also in toZonedDateTime() methods in the documentation, but those are not implemented yet. See: #592
Strings are allowed in the methods that have a Temporal.Instant argument, and both strings and property bags are allowed in the methods that have a Temporal.DateTime argument. See: #592
Property bags were already allowed. See: #592
Also in toZonedDateTime() methods in the documentation, but those are not implemented yet. See: #592
Strings are allowed in the methods that have a Temporal.Instant argument, and both strings and property bags are allowed in the methods that have a Temporal.DateTime argument. See: #592
These operations will be used elsewhere to convert arguments to other methods, so change them into abstract operations. See: #592
Property bags were already allowed. See: #592
Also in toZonedDateTime() methods in the documentation, but those are not implemented yet. See: #592
Strings are allowed in the methods that have a Temporal.Instant argument, and both strings and property bags are allowed in the methods that have a Temporal.DateTime argument. See: #592
As noted by @ptomato in #240 (comment):
I agreed in a follow-up comment:
From what I can tell, the decision to not allow strings in
date.withTime()
happened in #237, but I'm still not sure on the rationale for doing so. A lot of the cookbook examples look more complicated than they should with the current spec. I know which one of these two options I'd prefer to read in a codebase:The main reason I think it should be reconsidered is that
Absolute.prototype.inTimeZone()
accepts aTimeZone
OR a string (likewise forDateTime
). So if I can writeabs.inTimeZone('Australia/Lord_Howe')
instead ofabs.inTimeZone(Temporal.TimeZone.from('Australia/Lord_Howe'))
, why can't I writedate.withTime('13:45')
ortime.withDate('2020-11-01')
?Edit for clarity after comments: My proposal is to allow whatever is allowed in the first argument of
Date.from()
orTime.from()
, respectively. This would include the correct Temporal objects (as it is now), strings, and property bags. Extra option arguments (e.g.overflow
) would not be allowed — anyone wanting to use them can use the current technique of constructing the object via.from()
directly.The text was updated successfully, but these errors were encountered: