Thai culture date gets converted twice - reactjs

export const lastUpdated = createSelector(
learningDetails,
ld =>
{
(ld.lastModifiedDate) &&
Intl.DateTimeFormat('th-TH', {
month: '2-digit',
day: '2-digit',
year: 'numeric',
}).format(new Date(ld.lastModifiedDate))
}
);//returns >> 3107-05-21
Above is a function where the last update date is being picked up, since the ld.lastModifiedDate received from service is already in Thai time-zone by formatting the date value, it again gets converted.
For eg.:
Original date : 2021-05-21 in UTC
Converted on the the service layer to Thai time-zone to 2564-05-21 i.e. 543 years ahead (as Thai culture follows Buddhist calendar).
Service returns & populates ld.lastModifiedDate to 2564-05-21 which then gets formatted using Intl.DateTimeFormat as per culture this leads to bump up of the year again by 543 years. (2021+543+543) which is incorrect. Is there a dynamic way to avoid the second time conversion for all cultures irrespectively along with formatting.
Note: We can't change the legacy service layer to return UTC/original date as it is being invoked by other internal functions.

Got the solution from : https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat/DateTimeFormat
Basically, by appending '-u-ca-gregory' to the culture solves the issue.
Default considering Gregorian calendar.
export const lastUpdated = createSelector(
learningDetails,
ld =>
{
(ld.lastModifiedDate) &&
Intl.DateTimeFormat('th-TH-u-ca-gregory', {
month: '2-digit',
day: '2-digit',
year: 'numeric',
}).format(new Date(ld.lastModifiedDate))
}
);//returns >> 2564-05-21

Related

Calculate Day of a week for current year from Moment

I am making a Alarm System for Mon, Tue, Wed, Thu, Fri Sat and Sun separate. Let's say i am setting an alarm for Tuesday than i need all Tuesdays of current Month and atleast for current year till the alarm is Off. I want to achieve it using moment.
I am using Package - 'moment-weekdaysin', this is not giving me proper result. It is giving me incorrect date.
code - moment().weekdaysInMonth('Monday')
I've not used moment-weedaysin before but it should share most of the same API as core moment. The code below will capture all Tuesday dates in the format of Month-Day-Year (MM-DD-YYY) from the current date til the end of the current year. You can change the parameter for any other days 1-7 (Monday-Sunday).
import moment from 'moment';
const getOccurrencesOfDayThisYear = (day = 1) => {
let startDate = moment();
const endOfYear = moment().endOf('year');
const extractedDates = [];
while (startDate.isBefore(endOfYear)) {
if (moment(startDate).day() == day) {
extractedDates.push(moment(startDate).format('MM-DD-YYYY'));
}
startDate = moment(startDate).add(1, 'days');
}
return extractedDates;
};
// 2 represents Tuesday; 1 being Monday and 7 being Sunday
getOccurrencesOfDayThisYear(2)
There might be a more sophisticated way of performing this through various moment methods.

Check if event is in future - Yup validation

I'm currenlty working on yup validation for a page in project. I'm stuck on the following:
User chooses date, timezone and specific time of the event (he can choose times from 00:00 to 23:45 every fifteen minutes). Now, I need to validate if chosen time is in the future. I am really confused: should I first convert current moment to users chosen timezone, or convert user's moment to local timezone, or something else.
Here's what I did first when I was careless about the timezone:
[keys.startTime]: yup
.number()
.required(errors.required)
.when(['date'], (date, schema: any) => {
const currentTimeInMinutes = moment().hours() * 60 + moment().minutes()
if (
moment(date).date() === moment().date() &&
moment(date).month() === moment().month() &&
moment(date).year() === moment().year()
)
return schema.min(currentTimeInMinutes, errors.pastTime)
}),
But then I realised that I didn't take into account chosen timezone.
Start time here represents number of minutes from 00:00 to chosen time, for example if user chooses 00:15, startTime will be 15.
Thanks in advance.
You need to compare - the current time (at the point of submission) with the user's selected/entered date and startTime both in the user's selected zone.
// Calculate the offset of the timezone that user selected from UTC
const utcOffset = '+05:30'; // Example of a time zone in India
const currentTime = moment().utcOffset(utcOffset);
const userSelectionTime =
moment(date).utcOffset(utcOffset)
.startOf('day')
.add(startTime, 'minutes');
/*
* Check if the difference between the `userSelectionTime` and the `currentTime`
* is greater than 0 minutes (you can change this as per your requirements)
*/
const selectionIsValid = userSelectionTime.diff(currentTime, 'minutes') > 0;

Parsing this format of data into a new one?

I have a format which returns me some dates and I need to parse it into something else which I find a little bit complicated.
The data format is Mon Dec 24 2018 9:00:00 as a startDate for example and Friday Dec 28 2018 17:00:00 as an endTime for example. What happens here is that I select I want someone to start on Monday at 9 until 17 everyday, but what my data does is makes it look like he's working non-stop.
I have tried mapping over it and putting it onto objects with days of the week and start and end times, but I ran into a problem because I create the object like
dates : {
monday: {
start: 9:00,
end: 18:00
},
tuesday: {
start:9:00,
end:18:00
}
// etc for everyday of the week
}
But, what if I only need Monday through Thursday, for example, that would be a problem. Anyone has any idea, how could I do that, in any other way? I was thinking about using moment.js.
I'm not sure if I understand your question, but I think you want to list all days between two different dates, here is an example of function that iterates over days by using moment.isSameOrBefore and moment.add functions, hope this help:
function toDays(startDateString, endDateString) {
const startDate = moment(startDateString, 'dddd MMM DD YYYY');
const endDate = moment(endDateString, 'dddd MMM DD YYYY');
const dates = {};
while(startDate.isSameOrBefore(endDate, 'day')) {
const currentDay = startDate.format('dddd');
dates[currentDay] = {start:'9:00', end:'18:00'};
startDate.add(1, 'days');
}
return dates;
}
const result = toDays('Monday Dec 24 2018', 'Friday Dec 28 2018');
console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.23.0/moment.min.js"></script>

Add date format into date regex

I am getting date format like this /Date(1495111091673)/.I have created one custom filter to change date format.
app.filter('jsonDate', function () {
return function (date) {
return new Date(date.match(/\d+/)[0] * 1);
}
})
This filter returns date like this.
Thu May 18 2017 18:08:11 GMT+0530 (India Standard Time)
But I want it as standard format like dd/MM/yyyy so I have edited my filter code like this:
app.filter('jsonDate', function () {
return function (date) {
return new Date(date.match(/\d+/)[0] * 1, 'dd MMMM # HH:mm:ss');
}
})
Is it correct?
This filter returns date like this
Thu May 18 2017 18:08:11 GMT+0530 (India Standard Time)
No it doesn't, that's just how your console (or whatever) is choosing to display the Date instance (via Date.prototype.toString()).
I'd just use AngularJS's date filter ~ https://docs.angularjs.org/api/ng/filter/date.
For example (where dateFormat is your "/Date(1495111091673)/" formatted string)
{{dateFormat | jsonDate | date : 'shortDate'}}
Or in JS
let parsed = $filter('jsonDate')(dateFormat)
let dateString = $filter('date')(parsed, 'shortDate')
or via DI
.controller('controllerName', ['dateFilter', 'jsonDateFilter',
function(dateFilter, jsonDateFilter) {
let dateString = dateFilter(jsonDateFilter(dateFormat), 'shortDate')
}])

How exclude especific days in Watson conversation

I'm doing a service chat and I'd like to extract days that correspond to Sunday. For exemple:
Watson: Choose a date
user: day 30
Watson: We don't open this day, because it's a Sunday.
The problem is.. the Sundays of this month are not the same as next month.. I tried with an array inside the context with Sundays days of this month(ex: "2","9","16","23","30"), but the Conversation didn't understand that day 30 is a Sunday.. Could anyone help me please?
Tks! :)
In this case, unfortunally, #sys-date does not work equal #sys-number.
In this case with #sys-number, if user type 1, #sys-number recognize and can use #sys-number:1 with condition inside the flow.
Unfortunally, #sys-date doesn't.
In this case, for get the date with javascript you can use:
new Date() //get the date NOW
new Date(milliseconds)
new Date(dateString)
new Date(year, month, day, hours, minutes, seconds, milliseconds)
You can see the now() is the same format to get date:
new Date(year, month, day, hours, minutes, seconds, milliseconds)
And you can convert the #sys-date to the same format, and use this to verify the name of the date.
Get the day with context variable and use code in your application. For example:
var days = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];
var dateObject = new Date(dateParts[2], dateParts[1] - 1, dateParts[0]);
var dayName = days[dateObject.getDay()];
console.log(dayName);
And make some condition... for example:
if(dayName === 'Sunday'){
data.output.text[0] = "We don't open this day, because it's a Sunday."
}
I code this and works fine, see:
function dayRequest(data, req, res){
console.log('works the true condition context')
var dateString = data.context.day; //context variable with <? #sys-date ?>
var dateParts = dateString.split("/");
var dateObject = new Date(dateParts[2], dateParts[1] - 1, dateParts[0]);
var days = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];
var dateObject = new Date(dateParts[2], dateParts[1] - 1, dateParts[0]);
var dayName = days[dateObject.getDay()];
console.log(dayName);
if(dayName === 'Sunday'){
data.output.text[0] = "We don't open this day, because it's a Sunday.";
return res.json(data);
}
}
Check my app:
In this case, you can use now to get the date and in your application you'll end a message if the day is Sunday... You can use context variable for this too, but, you need set all dates.. And with this code, you'll check the date and your application will send a message.
Summary: convert your #sys-date to the same format now() and use my code to send a message for your user if the day is Sunday. I created one context variable with to save the date after request and in the next flow I create one context with dayTrue: true inside conversation flow. In my application, I created one condition in my updateMessage() if data.context.date === true, my function dayRequest() will execute.

Resources