javascript - how to get date format from string date - javascript

How can I get date format (for example: DD/MM/YYYY) from already formatted date (for example: 1/9/2021). Also can I somehow achieve not to swap US Date and NOT US Date (DD/MM/YYYY vs. MM/DD/YYYY).
I'm using Angular project (in case there is a Angular solution)

You can use moment.js to parse date like:
import moment from "moment";
const newDate = moment("1/9/2021", "MM/DD/YYYY").format("DD/MM/YYYY");
// newDate = 09/01/2021

The short answer is you can't reliably determine the format that a user inputs a date string based on system settings, even if you had access to them, because the user might input the value in a different format. E.g. in Britain it's common to use day/month/year, but if you check out the date on The Times newspaper you'll see something like "Sunday September 5 2021".
That's one reason why date pickers are used, however many users still prefer to enter dates manually and often find date pickers annoying.
Anyway, it seemed like a bit of fun to determine the localised format that Intl.DateTimeFormat produces for the default system language. This is of course totally unreliable, whatever. :-)
This works because formatToParts returns the parts in an array in the order associated with the language, along with the separators.
function getDateFormat(lang) {
let d = new Date(2021,0,20);
let format = new Intl.DateTimeFormat(lang,{
year: 'numeric',
month: 'numeric',
day: 'numeric'
}).formatToParts(d).reduce((acc,part) => {
acc += part.type == 'literal'? part.value : part.type;
return acc;
}, '');
return format;
}
['default',
'en-GB',
'en-US',
'en-CA',
'nl-BX',
'ar'].forEach(lang => {
let langDefault = lang == 'default'? new Intl.DateTimeFormat('default').resolvedOptions().locale : null;
console.log('Lang ' + lang + (langDefault? ' (' + langDefault + ')':'') +
' format ' + getDateFormat(lang) + '.');
});

Related

Get Offset of the other Location in Javascript

I am in Asia and I want to calculate the offset of Australia. I know how to calculate the value of the offset the code is written below:
var timezone_offset = new Date().getTimezoneOffset();
But how to calculate it for the other locations? Anyone can guide me??
While this can be done in a short function, it would be best to use a library as there are many quirks to overcome. The offset can be determined using the timezone options of toLocaleString or Intl.DateTimeFormat.
However, if the language used for formatting matches the language of the location, it returns the timezone abbreviation instead of the offset. To deal with that, the following function first uses English and if that returns the abbreviation rather than an offset, it uses French. English offsets start with GMT, French offsets start with UTC. Where the offset is +0, they return just "GMT" or "UTC".
It's been tested with all IANA locations listed by wikipedia and seems to work for all of them but it should be tested more widely. Also, there should be feature tests before attempting to run it (i.e. support for Int.DateTimeFormat constructor, formatToParts method and the timeZoneName option).
// Return offset on date for loc in ±H[:mm] format. Minutes only included if not zero
function getTimezoneOffset(date, loc) {
// Try English to get offset. If get abbreviation, use French
let offset;
['en','fr'].some(lang => {
// Get parts - can't get just timeZoneName, must get one other part at least
let parts = new Intl.DateTimeFormat(lang, {
minute: 'numeric',
timeZone: loc,
timeZoneName:'short'
}).formatToParts(date);
// Get offset from parts
let tzName = parts.filter(part => part.type == 'timeZoneName' && part.value);
// timeZoneName starting with GMT or UTC is offset - keep and stop looping
// Otherwise it's an abbreviation, keep looping
if (/^(GMT|UTC)/.test(tzName[0].value)) {
offset = tzName[0].value.replace(/GMT|UTC/,'') || '+0';
return true;
}
});
// Format offset as ±HH:mm
// Normalise minus sign as ASCII minus (charCode 45)
let sign = offset[0] == '\x2b'? '\x2b' : '\x2d';
let [h, m] = offset.substring(1).split(':');
return sign + h.padStart(2, '0') + ':' + (m || '00');
}
let d = new Date();
console.log('Current offset for following locations:');
['Australia/Yancowinna',
'Australia/Lord_Howe',
'Australia/Canberra',
'Pacific/Honolulu',
'Europe/London',
'Canada/Eastern'
].forEach( loc =>
console.log(loc + ': ' + getTimezoneOffset(d, loc))
);
I don't suggest you use this function, it's really to show how messy getting the offset for a specific location can be.
Note that Australia has a number of offsets and some places observe daylight saving and others don't.
The accepted answer is correct, but if you are fine with some of the timezones to appear without the percise offset, a shorter way that doesn't require string parsing / manipulation will be:
// Return offset on date for loc in ±H[:mm] format.
function getTimezoneOffset(date, loc) {
return new Intl.DateTimeFormat('en-US', { timeZone: loc, timeZoneName: "shortOffset" })
.formatToParts(date)
.filter(e => e.type === "timeZoneName")[0].value
}
let d = new Date();
console.log('Current offset for following locations:');
['Australia/Yancowinna',
'Australia/Lord_Howe',
'Australia/Canberra',
'Pacific/Honolulu',
'Europe/London',
'Canada/Eastern',
'America/Los_Angeles',
'Asia/Kolkata'
].forEach(loc =>
console.log(loc + ': ' + getTimezoneOffset(d, loc))
);
You can see the the options for the timezone name format here [1]:
timeZoneName - The localized representation of the time zone name.
Possible values are:
"long" Long localized form (e.g., Pacific Standard Time, Nordamerikanische Westküsten-Normalzeit)
"short" Short localized form (e.g.: PST, GMT-8)
"shortOffset" Short localized GMT format (e.g., GMT-8)
"longOffset" Long localized GMT format (e.g., GMT-0800)
"shortGeneric" Short generic non-location format (e.g.: PT, Los Angeles Zeit).
"longGeneric" Long generic non-location format (e.g.: Pacific Time, Nordamerikanische Westküstenzeit)
[1]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat/DateTimeFormat#syntax:~:text=timeZoneName,Nordamerikanische%20Westk%C3%BCstenzeit)

ion-datetime: How to get date value without timestamp?

I'm using ion-datetime in ionic4 using NgModel to bind to a property, however, no matter what options I include in format, I always get the time with the timestamp included. ¿How can I remove timestamp from result so the final value of my property is something like "2019-04-22" instead of "2019-04-22T08:45:41.243-05:00"?
I tried: but, I'm still getting the timestamp
<ion-datetime max="2030" min="2019" [(ngModel)]="mydate" display-format="MMM DD, YYYY"></ion-datetime>
I expect the result to be like: "2019-04-22", but I keep getting: "2019-04-22T08:45:41.243-05:00"
If you want only date then I think split() method might works,beacause value we get from ion-datetime is a string.So we use split method which split string and convert it to an array,and you can get date or time which thing you want with the help of index as follow:
var dateFormat = mydate.split('T')[0];
console.log(dateFormat);
// 2019-04-22
You can format the date with Moment.js.
<ion-datetime displayFormat="MMM DD, YYYY" max="2030" min="2019" [(ngModel)]="mydate" (ionChange)="doSomething(this.mydate)"></ion-datetime>
import * as moment from 'moment';
doSomething(date) {
console.log('date', moment(date).format('YYYY-MM-DD')); // 2019-04-22
}
You can use custom picker options to set custom buttons, it returns an object with all the variables in separate keys, so it makes it easier to edit the way you want it to display
To do so, you would insert this in your ion-datetime
[pickerOptions]="customPickerOptions"
and in your .ts file
this.customPickerOptions = {
buttons: [
{
text: 'Save',
handler: (time) => {
console.log('time', time);
}
},
{
text: 'Cancel',
handler: e => {
modalCtrl.dismiss(e)
}
}
]
}
Hope this helps
<ion-datetime
displayFormat="DD.MM.YYYY"
presentation="date"
[(ngModel)]="date"></ion-datetime>
<div>{{date.split('T')[0]}}</div>
in Ts file
data:any='';
You can use moment.js
in your file.page.html
<ion-datetime [(ngModel)]="mydate" placeholder=""></ion-datetime>
in your file.page.ts
import moment from 'moment';
<!-- to pass data to your API -->
mydate = moment(mydate).format('YYYY-MM-DD');
<!-- to view in console -->
yourFunction(mydate) {
console.log('date', moment(mydate).format('YYYY-MM-DD'));
}
May this answer helps. I understand how frustrating it can be to find the answer we are looking for.
Edit2: toLocaleFormat is not widely accepted. Here is a post on alternatives. You could just split it around the T.
const dateArray = fullDateString.split('T');
if (dateArray.length > 0){
const partYouWant = dateArray[0];
}
Edit: From the Ionic docs
It's also important to note that neither the displayFormat or
pickerFormat can set the datetime value's output, which is the value
that is set by the component's ngModel. The format's are merely for
displaying the value as text and the picker's interface, but the
datetime's value is always persisted as a valid ISO 8601 datetime
string.
Here is a better answer:
const dateObject = new Date(this.mydate);
const dateString = dateObject.toLocaleFormat('%Y-%m-%d');
An input for new Date can be a date string defined as:
String value representing a date. The string should be in a format
recognized by the Date.parse() method (IETF-compliant RFC 2822
timestamps and also a version of ISO8601).
I'm guessing you are trying to access this.mydate in your code.
You have several options, best represented by this stack overflow post.
this.mydate.toLocaleFormat('%Y-%m-%d');
This function will take a Date object and convert it to the string in the format you requested. All the options you can put in the options are here.
There are also plenty of other options shown in the stack overflow post above.
install date-fns by npm i --save date-fns
import {format} from "date-fns"; in your .ts file
let date_x = "2019-11-30T14:42:30.951+08:00";
format(new Date(date_x), "yyyy-MM-dd");
you should get as result in console => '2019-11-29'
This is the best way to get the exactly time
First Create the $event method like this
changeTime(e) {
this.sentTempTime = "";
let hoursMinutes = e.split(':');
this.sentTime = this.formatTime(hoursMinutes);
}
after that create the formatTime() method like this
formatAMPM(date) {
var hours = date[0].toString().split('T'); //22
var minutes = date[1]; //11
var ampm = hours[1] >= 12 ? 'pm' : 'am'; //22 >=12 yes == pm
hours = hours[1] >= 12 ? hours[1] - 12 : hours[1]; //22 >= 12 ? 22-12=10
var strTime = hours + ':' + minutes + ampm;
return strTime;
}
after that you can able to get the time like this 08:15pm
In Ionic 6 you just need the presentation property.
Set it to date and it will only render the date picker, without the time picker.
<ion-datetime presentation="date"></ion-datetime>
See the presentation property in the docs for more details.

momentjs for only time value

I use momentjs to work with date and time
let dateAndTime = moment(component.props.data.value, moment.ISO_8601);
let date = '',
time = '';
if (dateAndTime) {
if (moment(dateAndTime, 'YYYY-MM-DD', true).isValid()) {
date = moment(dateAndTime).format('YYYY-MM-DD');
}
if (moment(dateAndTime, 'HH:mm', true).isValid()) {
time = moment(dateAndTime).format('HH:mm');
}
}
this code works just fine if component.props.data.value contains date and time like 2018-05-22 14:45 or if it contains only date like 2018-05-22. The problem is sometimes component.props.data.value contains only time like 14:45, so moment(component.props.data.value, moment.ISO_8601) doesn't create moment object and code below doesn't execute. Is there any way to handle case only for time?
You can use moment(String, String[]), as the docs says:
If you don't know the exact format of an input string, but know it could be one of many, you can use an array of formats.
This is the same as String + Format, only it will try to match the input to multiple formats.
Your first line of code could be like the following:
let dateAndTime = moment(component.props.data.value, [moment.ISO_8601, 'HH:mm']);

Plotly.js setting timezone for type:"date"

I'm working on a graph to display a status over time. All the data is in unix formatting. I display the data in my title using javascript (new Date(data)).toUTCString. This is the same data used for the graph but the graph is running 1 hour early. Image
Here is my layout config:
layout = {
"showlegend": true,
"title": new Date(min).toUTCString() + " to " + new Date(max).toUTCString(),
"xaxis": {
"autorange": true,
"range": [
min,
max
],
"title": "Time",
"type": "date" //if I change this to scatter, I get the unix values
}
}
Plotly.newPlot('graphMain', temp, layout); //temp contains the arrays
I'm currently residing in Austria (UTC+01:00).
Anyone have an idea for this?
Plotly doesn't currently support timezones.
You might want to use something like moment.js timezone if you need to precompute datetime to a local timezone or to UTC. Or you can do it manually if you like.
Today, I think Plotly.js still doesn't support timezones, or at least I couldn't find it. This is how I solved it, but, please, if you have a better solution I'd be glad to hear about!
I suppose the original format of the dates is yyyy-mm-ddTHH:MM:SSZ, then you change the format using the function in https://stackoverflow.com/a/74341794/11692632, which gets the timezone of the pc.
function fmt(date, format = 'YYYY-MM-DD hh:mm:ss') {
const pad2 = (n) => n.toString().padStart(2, '0');
//These functions get the date from the browser timezone, in my case 'Europe/Madrid'
const map = {
YYYY: date.getFullYear(),
MM: pad2(date.getMonth() + 1),
DD: pad2(date.getDate()),
hh: pad2(date.getHours()),
mm: pad2(date.getMinutes()),
ss: pad2(date.getSeconds()),
};
return Object.entries(map).reduce((prev, entry) => prev.replace(...entry), format);
}
> date = '2022-12-15T10:00:00Z'
'2022-12-15T10:00:00Z'
> newDate = new Date(date)
2022-12-15T10:00:00.000Z
> fmt(new Date(date))
'2022-12-15 11:00:00'
NOTE, of course, if you are using unix time, it would also work
> date = 1671100918000
1671100918000
> newDate = new Date(date)
2022-12-15T10:41:58.000Z
> newDate.toLocaleString('se-SE', { timeZone: 'Europe/Madrid' })
'2022-12-15 11:41:58'
So, if my array of dates is dates, to translate the dates to my timezone you should do:
> const tz_dates=dates.map(date=>fmt(new Date(date)))

Locale specific date without year

I am using https://github.com/abritinthebay/datejs/ for date formatting due to locale support. However, is it not possible to get a full date time without year?
Example
Input date:2014/09/20 20:00:00
Output date: 09/20 20:00
And it has to respect locale settings!
Looks like since ES2015 you can just skip first parameter and set only 'options' parameter, in that way locale will be applied:
new Date().toLocaleString(undefined, {
month: "short", day: "numeric",
hour: "numeric", minute: "numeric", second: "numeric"
}) // "Jul 11, 5:50:09 PM"
I didn't find the way to remove comma between date and time. For that case string formatting can be used:
const dateTime = new Date();
const datePart = dateTime.toLocaleDateString(undefined, {month: "short", day: "numeric"});
const timePart = dateTime.toLocaleTimeString();
const result = `${datePart} ${timePart}`;
// "Jul 11 5:57:10 PM"
console.log(new Date().toLocaleString('en-En',{weekday: "long", month: "long", day: "numeric"}))
You can change this options as you want.
To format a date as month/day hour:minute with Date.js you'd call toString with the format 'MM/DD HH:mm' to get two digits for all values, e.g.:
console.log(new Date().toString('MM/dd HH:mm'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/datejs/1.0/date.min.js"></script>
Attempting to determine the format that the user expects to see is very problematic, whether it's referred to as "culture", "locale" or just "preference". Javascript doesn't have access to system settings and the browser doesn't reveal them. You can try to guess based on the output of Date.prototype.toLocaleString, but that is entirely implementation dependent and doesn't necessarily conform to user preferences.
One common approach is to use an unambiguous format so user preferences don't matter, e.g.
console.log(new Date().toString('dd-MMM HH:mm'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/datejs/1.0/date.min.js"></script>
Another approach is to have an unambiguous default format, then allow the user to select from a few supported formats and store the preference.
There is also the built–in Date.prototype.toLocaleString, which is pretty unreliable but some browsers support the optional ECMA-402 Intl formatting options. It's pretty ordinary as a formatter so really can't be recommended when there are libraries that do the job so much better, e.g.
var options = {
month: 'short',
day : '2-digit',
hour : '2-digit',
minute:'2-digit'
};
// Browser dependent, something like en-us: Jan 21, 8:39 AM
console.log('en-us: ' + new Date().toLocaleString('en-us',options))
// Browser dependent, something like en-gb: 21 Jan, 08:39
console.log('en-gb: ' + new Date().toLocaleString('en-gb',options))
Yet another approach is to write your own parser and formatter that does just what you need. If you only need to support one or two formats, it's pretty straight forward, e.g.
// input format yyyy/mm/dd hh:mm:ss
function parseDateString(ds) {
var d = ds.split(/\D+/);
return new Date(d[0], --d[1], d[2], d[3], d[4], d[5]);
}
// Return date string as mm/dd hh:mm
function formatDate(d) {
function z(n) {
return (n < 10 ? '0' : '') + n
}
return z(d.getMonth() + 1) + '/' + z(d.getDate()) +
' ' + z(d.getHours()) + ':' + z(d.getMinutes());
}
console.log(formatDate(parseDateString('2014/09/20 20:00:00'))); // 09/20 20:00
So you can replace an entire library with less than a dozen lines of code. :-)

Categories

Resources