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
Date Manipulating/Formatting Functions #538
Comments
I suspect this is in regards to #536 as well as other things such as As far as #536 is concerned, I believe that at least two of the snippets could be combined and that we could add them to the main repository as they have valid use-cases for people who need to do some Date string manipulation without having to include a library. My opinion about date manipulation/format functions is that we should consider these factors:
Now, (1) is not always obvious, so this is why we review PRs and decided what we want to keep. (2) and (3) should be quite obvious just from reading the code - if something has to use ISO8601 or whatever, we should avoid it, if we return a result that is not expected (like we could get from Based on this opinion, here's my proposal for #536 (which I will also comment there):
|
Hey @skatcat31 Thanks for bringing up this issue!!! @Chalarangelo I totally believe if we are not careful things can get really sloppy, annoying 😫, and troublesome 😭 really fast. If we are to update and add a lot of other date snippets we need to do so carefully, using native
So it can also work with the other 20 ~ 30 or so I definitely think all but const getColonTimeFromDate = _ => new Date().toTimeString().slice(0, 8); Which returns getColonTimeFromDate() // "13:07:00" Which also looks like a digitalClock I believe a good rule of thumb should be if it doesn't use native |
I'm of the feeling that if we're going to do anything with dates we expect something similar to an ISO8601 date string for the parts we want so that no matter what library they got the string from, our behavior is consistent throughout all of our snippets. |
As for #536 I believe it should be addressed after this conversation |
@skatcat31 Yup Yup Agreed!
The question now become's the following. How much and/or what exactly is allowed/expected? Should potential contributors do the following adhering only to const foo = () => {
let time = new Date();
return `${time.getHours()}:${time.getMinutes()}:${time.getSeconds()}`;
} foo() // '3:12:32' or allow users to manipulate the Like using the following methods and/or more to parse .split()
.join()
.slice()
.map()
.splice() Or?? |
Wondering if as the contributor I can give my ¢2, I'm against using the As for using an ISO string, I'm in aggreance. |
Is method de-referencing part of ES6 or ES2017? |
@skatcat31 Can you explain a bit more what you meant when you asked the following?
In general? pertaining to Objects in memory? or ...? |
@kingdavidmartins sorry was confusing a spec with something that hasn't been released or even made it to stage 0 yet: Example as last I saw it: const test = () => 'a'
const getHours = () => 'b'
var dat = new Date()
dat[ getHours(), getMinutes(), getSeconds(), test()] // [hours, minutes, seconds, 'a']
dat{ hour: getHours(), minutes: getMinutes(), seconds: getSeconds() } // {hours: hours, minutes: minutes, seconds: seconds }
[getHours()] // ['b'] de-referencing methods was a suggestion to take an instance and return something that when a method was called, was checked against the referenced object before scoping. IIRC it was still not a staged proposal( no sponsor ), hence why I asked Turns out it's just still my confusion as it hasn't gotten a sponsor yet |
Sorry @skatcat31 I had no idea that was a thing. I only wrote it that way to keep it shorter. |
All good. I wouldn't expect to many people to know it was a thing. I'm pretty certain I'm the only one who reads the mailing list publications and TC39 in this group |
@skatcat31 ahhh gotcha 😆 |
Just to confirm @skatcat31, what is your take on the following?
or allow users to manipulate the Date() instances at will with whatever methods they so choose?
So we can get #536 sorted |
@kingdavidmartins pretty sure I said if we do any Date related things they should be to ISO8601 compatible strings to the extent that we need, not Date objects. For reference the following produces an ISO8601 compatible ms string new Date().toISOString() // we could use this for examples Now our methods are purely string related and have an exact time to work with ReasoningDate libraries that adhere to ISO8601 would also adhere to the fact that without a timezone on the end of the string it is parsed in local time, the exact thing that caused us to remove |
Addendum, if we only need parts of the ISO8601 string, the method should NOT expect a full one, just enough of one( as per ISO8601, partial ISO8601 are valid ) const toEnglishDate = isoString =>
(isoString = isoString.split(/\-|T/)) && [isoString[1], isoString[2], isoString[0]].join('/') toEnglishDate('2018-01-02') // '01/02/2018' |
... As a sidenote I think we can redo |
I'm at a loss for a way to put this into the contribution guidelines without sounding stupid |
@skatcat31 I believe we are in agreement on adhering to ISO8601 & partial ISO8601 However were I believe we disagree on is the process or rather the proposed structure at which we arrive at our conclusion. My question is why go about is the following way? const toEnglishDate = isoString =>
(isoString = isoString.split(/\-|T/)) && [isoString[1], isoString[2], isoString[0]].join('/') toEnglishDate('2018-01-02') // '01/02/2018' When it can also be accomplished the following const foo = () => {
let time = new Date();
return `${time.getMonth()+1}/${time.getDate()}/${time.getFullYear()}`;
} foo() // '1/18/2018' Isn't our objective to ensure that the returned value adheres to ISO8601 & partial ISO8601 which really comes down to how we format the output? Also since using the |
@kingdavidmartins like I stated before:
The method mentioned was that when passed to Date, ISO8601 strings without a timezone are parsed 'in local time', leading to confusing results for anyone who has no idea of the inner workings of ISO8601. By making it use a string absolutely, we alliviate that error in that '2018-01-01' will always be '01/01/2018' instead of '12/31/2017' or the current time only( the problem we experienced with foo() // a time
// adjust clock in system settings
foo() // a DIFFERENT time vs var d = new Date().toISOString()
toEnglishDate(d) // a time
// adjust system clock
toEnglishDate(d) // the SAME time The top only has the use case of "Current time in English Date Format" the bottom has the use case of "Format an ISO8601 time in English Date Format", which also covers the previous case |
I think I get it. If a user unknowingly passes in an improper ISO8601 string the Date instance they use from whatever API will give them an unexpected result instead of the function acting on that string directly. And by expecting a string according to the ISO8601 rather than the result of the Date API, we can expect a consistent format? This makes it unfortunate that you need to parse this string in every function unless this repository adopts a functional approach allowing other snippet functions to be nested in higher order functions. I'm not sure whether use of standard functions & methods has changed in contribution, but is Date not considered? Both methods (@skatcat31, @kingdavidmartins) encourage the understanding of ISO8601, either by explicitly showing how to process the string, or by requiring a proper input. |
@skatcat31 Although I understand the reasoning behind what your saying, what I'm saying is also the following. I don't think its practical and can't see how's it's confusing If I live in NY and someone else live in Spain, or in another time zone let's say. Shouldn't we see different time's? shouldn't we see the time on our machines? And see our local time with regards to our timezone? Also although by using |
@skatcat31 I believe it really comes down to the assumption of how our user/users will use Time/Date related snippets and what we believe their expected return should be |
var a = new Date('2018-01-01')
var b = time =>
`${time.getMonth()+1}/${time.getDate()}/${time.getFullYear()}`
b(a) // "12/31/2017" because I'm PT(-800/-700) The above is why I say we should avoid the Date libraries. Pointed out to us by @fejes713 when toEnglishDate was around // convert times on comments into Dates for display
comments.map(copySimple).map(inWith('date',toEnglishDate)).forEach(attachToPost) This very common use case is why toEnglishDate shouldn't only display the current time, but instead take any compatible input toEnglishDate(new Date().toISOString())
toEnglishDate(new Moment().toISOString())
toEnglishDate(new Timeless().toISOString()) achieves the same as your code snippet, and is able to be implemented with several libraries, or a string from a data source General, re-useable code is always better than specific use case code if there is a chance it can be used in more than one place IMO In regards to seeing different timezones: new Date('2018-01-01T00:00:00').toISOString() != new Date('2018-01-01T00:00:00Z').toISOString() While that can be desired, it can also be greatly confusing. A good example was the 2 weeks FB comments were displayed in local time, leading to comments saying they came from the past. People where very confused |
Possible compromise in functionality(not code) const toEnglishDate = (isoString = new Date().toISOString()) =>
(isoString = isoString.split(/\-|T/)) && [isoString[1], isoString[2], isoString[0]].join('/') toEnglishDate() //display the current English Date
toEnglishDate('2018-01-01') // 01/01/2018 regardless of timezone |
@Emgo-Dev pretty close. However parsing ONLY needs to be done to the extent our snippet needs of the string. More complex regex could be used for generating different functions and it gets a little confusing and it would be required every time, but it also means each snippet is completely standalone. As for |
@skatcat31 I believe you are onto something. having dateMethods accepting date strings from different libraries can and will deff make our methods more flexible I'm proposing the following format const dateSnippet = (str, ISO = false) => {
// Code
} An example being the following const tomorrow = (dateStr, ISO = false) => {
let t = dateStr === undefined || typeof(dateStr) === 'boolean' ? new Date() : new Date(dateStr);
t.setDate(t.getDate() + 1);
let month = `${t.getMonth()+1}`.padStart(2, '0');
let day = `${t.getDate()}`.padStart(2, '0');
let isTomorrow = `${t.getFullYear()}-${month}-${day}`;
if (typeof(ISO) === 'boolean' && ISO === false) {
return isTomorrow;
} else {
let ISOTomorrow = new Date(isTomorrow).toISOString()
return (isoT = ISOTomorrow.split(/\-|T/)) && [isoT[0], isoT[1], isoT[2]].join('-')
}
}; Resulting with the following tomorrow('Sun Dec 31 2028') // 2029-01-01
tomorrow('Feb 28 2028') // 2028-02-29
tomorrow('2018-05-3') // 2018-05-04
tomorrow('2018-01-01T00:00:00') // 2018-01-02
tomorrow('Wed Oct 05 2011 16:48:00 GMT+0200 (CEST)') // 2011-10-06
tomorrow('Wed Oct 05 2011 00:48:00 GMT+0200 (CEST)', true) // 2011-10-05 This way we can always default to local time & then pass in true or anything else as a second arg to get the ISO formatted using the zero UTC offset *Note: *The |
Honestly, @kingdavidmartins, the overhead is too long for this kind of thing. I mean we need to figure this out somehow, but it's gonna confuse readers a lot and make us tag all our |
@kingdavidmartins sadly I agree with @Chalarangelo about the overhead. It's much easier to reason that we're restricting them to an ISO8601 compatible string for us to manipulate, even if it means we have regex in place to parse the string. It leads to completely compatible implimentations with the only knowledge being "Takes a string like |
I think we're beginning to approach two separate concerns. Interpreters, which @kingdavidmartins example behaves like, and formatters. Interpreters would provided good utility expanding But Formatters should return a formatted string from a single expected standard. I played around more with this idea of relying on regex and only an ISO format. I think it fits best for the repo. const getIsoDate = isoString => isoString.match(/\w{4}-\w{2}-\w{2}/)[0]
const getIsoYear = isoString => isoString.match(/^\w{4}/)[0]
const getIsoMonth = isoString => isoString.match(/\w{2}(?=-\w{2}T)/)[0]
const getIsoDay = isoString => isoString.match(/\w{2}(?=T)/)[0]
const getIsoTime = isoString => isoString.match(/\w{2}:\w{2}:\w{2}/)[0]
const getIsoHour = isoString => isoString.match(/\w{2}(?=:)/)[0]
const getIsoMinute = isoString => isoString.match(/\w{2}(?=:\w{2}\.)/)[0]
const getIsoSecond = isoString => isoString.search(/\w{2}(?=\.)/)[0] The only problem might be how specific they are. They'd be divided among many individual snippet files. They do what we've discussed but the regex becomes redundant. You could achieve a tomorrow result using the above like this. let date = new Date("January 15 2015 12:12:12").toISOString();
let year = getIsoYear(date)
let month = getIsoMonth(date)
let day = getIsoDay(date)
let tomorrow = `${year}-${month}-${day[0].concat(parseInt(day[1]) + 1)}` |
Having snippets with prerequisites is something we have discussed before and we have decided that we will never do this, as it goes against the core idea of the project. Every snippet has to be self-contained and understandalbe without prerequisites. I suppose that the only way to make this workable is to tag most of the date snippets |
I feel like at this point we've reached the conclusion: Keeping them in the main repo exposes us to a lot of confusing design patterns or hard to rely on libraries due to time differences. Because of this I'm of the opinion that we should not have Date or DateString formatting functions in the main repository. Due to an expanded required knowledge they are either too advanced, or too confusing unless you know the Date libraries or Regex or ISO8601. To this day many advanced and high level developers STILL have problems with Date logic |
So, in regards to existing snippets, should we keep the 3 In regards to #536, I suppose that |
After re-reading the whole thread, I think I have a suggestion about the Date snippets considerationsAs far as snippets that deal with date parsing and formatting are concerned:
I think the above rules should cover it all and keep everything safe and consistent, due to the fact that dealing with existing Opinions? @kingdavidmartins @fejes713 @skatcat31 |
This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for any follow-up tasks. |
Should we allow Date or time formatting related functions in the main repo?
While ubiquitous I feel like they would more belong in the archive section due to the reliance on a very confusing library and regional/national standards.
The text was updated successfully, but these errors were encountered: