Check if event is in future - Yup validation - reactjs

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;

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.

Convert normal string to datetime format

Is there any way to convert normal string 5pm into 2022-04-20T17:00:00.000Z format?
I have got this from backend but Im using timepicker in antd. It only accepts 2022-04-20T17:00:00.000Z format and it is in string format in my DB.
This should consistently give you the current date with the time attached
function convertToISO(timeString) {
const [hour12, ampm] = timeString.split(/(?=[ap]m$)/i)
const hour = hour12 % 12 + (ampm.toLowerCase() === 'pm' ? 12 : 0)
const date = new Date()
// Set time, adjusted for time zone
date.setHours(hour, -date.getTimezoneOffset(), 0, 0)
return date.toISOString()
}
console.log(convertToISO('5pm'))

How can I calculate the difference between two dates in Luxon?

I'm doing a project in React js and I need calculate the difference between dates.
The first one the user choose the startTime(state) and the endTime(state) and the program give the differecen in years, months and days ( this program is done and working).
Now I'm trying calculate the difference in days between the day 1-01-2022 and other date that the user choose.
I have tryed change the format but I receive errors.
//this is working
const date1 = DateTime.fromISO(endTime.toISOString());
const date2 = DateTime.fromISO(startTime.toISOString());
let durationDate = date1.diff(date2, ["years", "months", "days"]);
//--------------
//this is not working
const date3 = DateTime.fromISO(endTime.toISOString());
const dateNow = DateTime.now().startOf("year").toISO();
let dateTermination = endTime.diff(dateNow, ["years", "months", "days"]).toObject();
//----------------

When creating a tensor with an array of timestamps, the numbers are incorrect

Looking for some kind of solution to this issue:
trying to create a tensor from an array of timestamps
[
1612892067115,
],
but here is what happens
tf.tensor([1612892067115]).arraySync()
> [ 1612892078080 ]
as you can see, the result is incorrect.
Somebody pointed out, I may need to use the datatype int64, but this doesn't seem to exist in tfjs 😭
I have also tried to divide my timestamp to a small float, but I get a similar result
tf.tensor([1.612892067115, 1.612892068341]).arraySync()
[ 1.6128920316696167, 1.6128920316696167 ]
If you know a way to work around using timestamps in a tensor, please help :)
:edit:
As an attempted workaround, I tried to remove my year, month, and date from my timestamp
Here are my subsequent input values:
[
56969701,
56969685,
56969669,
56969646,
56969607,
56969602
]
and their outputs:
[
56969700,
56969684,
56969668,
56969648,
56969608,
56969600
]
as you can see, they are still incorrect, and should be well within the acceptable range
found a solution that worked for me:
Since I only require a subset of the timestamp (just the date / hour / minute / second / ms) for my purposes, I simply truncate out the year / month:
export const subts = (ts: number) => {
// a sub timestamp which can be used over the period of a month
const yearMonth = +new Date(new Date().getFullYear(), new Date().getMonth())
return ts - yearMonth
}
then I can use this with:
subTimestamps = timestamps.map(ts => subts(ts))
const x_vals = tf.tensor(subTimestamps, [subTimestamps.length], 'int32')
now all my results work as expected.
Currently only int32 is supported with tensorflow.js, your data has gone out of the range supported by int32.
Until int64 is supported, this can be solved by using a relative timestamp. Currently a timestamp in js uses the number of ms that elapsed since 1 January 1970. A relative timestamp can be used by using another origin and compute the difference of ms that has elapsed since that date. That way, we will have a lower number that can be represented using int32. The best origin to take will be the starting date of the records
const a = Date.now() // computing a tensor out of it will give an accurate result since the number is out of range
const origin = new Date("02/01/2021").now()
const relative = a - origin
const tensor = tf.tensor(relative, undefined, 'int32')
// get back the data
const data = tensor.dataSync()[0]
// get the initial date
const initial date = new Date(data + origin)
In other scenarios, if using the ms is not of interest, using the number of s that has elapsed since the start would be better. It is called the unix time

Ionic/Angular ion-datetime with condition

I have the following in Ionic and I'd like to let the user choose a datetime value but with one condition: If hour is equal to '21' then minutes must be '00' (not '30'), otherwise minutes value can be equal to '00' or '30'. Ideas?
<ion-datetime
hourValues="9,10,11,12,13,14,15,16,17,18,19,20,21 #hour"
[minuteValues]="hour != 21 ? '00,30' : '00'"
[(ngModel)]="time"
name="time"
required>
</ion-datetime>
It was not possible because the "minuteValue" is set first when u click on ion-datepicker to select date & time.
one way to achieve this is to compare your selected hour in .ts file and assign particular value based on hour to the minute like below.
In .html file.
<ion-datetime
hourValues="9,10,11,12,13,14,15,16,17,18,19,20,21 #hour"
minuteValues="0,30"
[(ngModel)]="time"
name="time"
displayFormat="MM DD,YYYY HH:mm"
(ionChange)="timeValue()"
required>
</ion-datetime>
In .ts file:
timeValue()
{
let hour = this.time.split('T')[1].split(':')[0];
let minute = this.time.split('T')[1].split(':')[1];
if(Number(hour) === 21)
{
minute = '00';
}
let date = new Date(this.timey);
date.setHours(Number(hour));
date.setMinutes(Number(minute));
console.log("------------"+date);
}

Resources