New to javascript here, and am trying to replace a specific event dates with text. Events dates are in the format #F #d, and I'd like to instead show "Christmas" if #F #d = December 25. Thanks in advance.
const eventdate = #F #d;
let dateswap;
if (eventdate == 'December 25') {
dateswap = "Christmas";
}
document.innerHTML = dateswap;
You can use an if statement to change the variable's value if it is equal to a specific date.
let date = 'December 25';
if (date === 'December 25') {
date = 'Christmas';
}
console.log(date); // value is now "Christmas"
Generally in the future it's always good to show your effort, but welcome to SO here's a freebie! :)
// Let's pretend this is what's supplying your date.
const date = new Date(),
christmasDay = new Date('December 25, 2021 00:00:01'),
output = document.getElementById('output-example'),
christmasMessage = 'IT IS CHRISTMAS! HO HO HO!';
// Now let's find out if it's christmas.
// First we see if month == 11 (because month works as array and starts count at 0 not 1)
// Then we check to see if the current day is the 25th with getDate()
// If the date matches we display a special christmas greeting, if not then something else.
// To see it work change "date" for .getMonth() and .getDate() below to "christmasDay"
// This way you can simulate the christmas day date to see the change.
isChristmas = (d) => {
return d.getMonth() == 11 && d.getDate() == 25;
}
// if you wanted an if example
if (isChristmas(date)) {
output.innerHTML=`<h1 style="color:red">${christmasMessage} - ${date.toLocaleDateString('en-US')}</h1>`;
} else {
output.innerHTML=`<h1 style="color:blue">Sorry, not yet christmas :( - ${date.toLocaleDateString('en-US')}</h1>`;
}
// --------------------------------------------------
// Or just set a function to return accordingly
isTodayChristmas = (d) => {
// with a ternary example
return isChristmas(d) ? christmasMessage : d;
}
// We'll use christmas day var to ensure we're sending the christmas date for this example.
console.log(isTodayChristmas(christmasDay));
<div id="output-example"></div>
Related
I have this cypress test where Im checking for a correct billing date. Our website has monthly subscriptions and it works as follows:
If you start your subscription on January 31st, your next billing date will automatically be on the 1st of March since February has only 28 days.
Same if you start your subscription on the 31st of March, then your next billing date will be on the first of 1st of May since there is no 31st in April and it automatically changes to the first day of the next month.
Starting on other normal dates like the 15th will always be the same date (15th) of the next month etc..
My issue is when testing this with cypress, i always get the last day of the next month. For example if i test that Im gonna start my subscription on the 31st of March, my test will have 30th of April as an expected result, which is not correct since i want the expected result of my test to be 1st of May.
I am using this function but i cant seem to make it work properly since there are many differences in the months.
export const getBillingDate = (todayDate: string, months: number) => {
const date1 = new Date(todayDate)
const date2 = new Date(todayDate)
date1.setDate(1)
const daysInNextMonth = getDaysInMonth(addMonths(date1, months))
date2.setDate(Math.min(date2.getDate(), daysInNextMonth))
return format(addMonths(date2, months), 'MMMM do, yyyy')
}
I would really appreciate anyone's help with this since i am new to Cypress and testing in general. (Sorry english is not my first language)
Both dayjs and javascript new Date() fail to add all the dates exactly as you want.
But you can use dayjs().daysInMonth() to get results exactly as per your description,
const getBilling = (startDate) => {
const [year, month, day] = startDate.split('/')
const sd = dayjs(startDate)
const firstOfNextMonth = sd.month(sd.month() + 1).date(1)
const daysInNextMonth = dayjs(firstOfNextMonth).daysInMonth()
let end;
if (daysInNextMonth < day) {
end = `${year}/${+month+2}/${1}` // always bump to 1st day of month + 2
} else {
end = `${year}/${+month+1}/${day}`
}
return dayjs(end, 'YYYY/MM/DD').format('YYYY/MM/DD')
}
it('gets billing date, accounting for short months', () => {
//Jan
expect(getBilling('2022/01/15')).to.eq('2022/02/15')
expect(getBilling('2022/01/31')).to.eq('2022/03/01')
//Feb
expect(getBilling('2022/02/15')).to.eq('2022/03/15')
expect(getBilling('2022/02/28')).to.eq('2022/03/28')
//Mar
expect(getBilling('2022/03/15')).to.eq('2022/04/15')
expect(getBilling('2022/03/31')).to.eq('2022/05/01')
})
Day.js already exists to do date math.
You can use their .add() to add 30 days to a date dayjs().add(30, 'day').
You can also format the dates with .format() to format the way you want it dayjs('2019-01-25').format('DD/MM/YYYY') // '25/01/2019'
Your requirements are a little unusual. Typically when adding a month and it overflows, the requirement is to return the last day of the month, not the first of the following month. But it's not difficult, just get the starting date (day in month), add a month, and if the resulting date isn't the same, set it to the 1st, e.g.:
function addBillingMonth(date = new Date()) {
let d = new Date(+date);
let dayNum = d.getDate();
d.setMonth(d.getMonth() + 1);
if (dayNum !== d.getDate()) {
d.setDate(1);
}
return d;
}
// Examples
[ new Date(2021,11,31), // 31 Dec
new Date(2022, 0,15), // 15 Jan
new Date(2022, 0,31), // 31 Jan
new Date(2022, 2,31), // 31 Mar
].forEach(d => console.log(d.toDateString() +
' next bill: ' + addBillingMonth(d).toDateString())
);
You have a months parameter, if you want to increase by more that one month you should calculate each month separately.
'dayjs` definitely gives you more options to play with.
const expect = chai.expect
const addBillingMonth = (start) => {
let next = start.add(1, 'month')
if (start.date() !== next.date()) {
next = next.add(1, 'month').startOf('month')
}
return next
}
const getBilling = (startDate, months = 1) => {
let result = dayjs(startDate)
for (let i = 0; i < months; i++) {
result = addBillingMonth(result) // repeat for each month
}
return result.format('YYYY/MM/DD')
}
expect(getBilling('2022/01/15')).to.eq('2022/02/15')
expect(getBilling('2022/01/31')).to.eq('2022/03/01')
expect(getBilling('2022/02/15')).to.eq('2022/03/15')
expect(getBilling('2022/02/28')).to.eq('2022/03/28')
expect(getBilling('2022/03/15')).to.eq('2022/04/15')
expect(getBilling('2022/03/31')).to.eq('2022/05/01')
<script src="https://cdnjs.cloudflare.com/ajax/libs/chai/4.3.6/chai.min.js"></script>
<script src="https://unpkg.com/dayjs#1.8.21/dayjs.min.js"></script>
I want to validate dates by Javascript and found this nice answer:
https://stackoverflow.com/a/1353711/3391783
but when i try to use it to validate dates, it seems like Javascript is auto-correcting my date by taking the closest valid date. so this will return true even though 2014-11-31 is not a valid date (Javascript months start at 0, so 10 equals November):
function isValidDate(d) {
if ( Object.prototype.toString.call(d) !== "[object Date]" )
return false;
return !isNaN(d.getTime());
}
var test_date = new Date(2014, 10, 31);
console.log( test_date );
console.log( isValidDate(test_date) );
seems like creating the Date is automatically switching it to 2014-12-01 which is a correct date.
but I would like to be able to validate user input without changing it.
So how can i create an invalid new Date() in Javascript?
Or is there a much simpler way to do this?
You can use the auto-correction in the Date object to validate the date. Just check the input against what you have in the Date object:
var y = 2014, m = 10, d = 31;
var test_date = new Date(y, m, d);
var valid =
test_date.getFullYear() == y &&
test_date.getMonth() == m &&
test_date.getDate() == d;
document.write(valid);
When it comes to handling dates in JavaScript, I'm a big fan of Moment.js. As you can see here, they do a good job of validating dates: http://momentjs.com/docs/#/parsing/is-valid/
new Date(2013, 25, 14).toString(); // "Sat Feb 14 2015 00:00:00 GMT-0500 (EST)"
moment([2015, 25, 35]).format(); // 'Invalid date'
Here's a function I wrote a while back that demonstrates Guffa's solution.
function isValidDate(checkDate) {
if(!/\d\d\/\d\d\/\d\d\d\d/.test(checkDate)) {
return false; // checkDate is not formatted as ##/##/####
} else {
// split checkDate into three pieces
var strMM = checkDate.split('/')[0];
var strDD = checkDate.split('/')[1];
var strYYYY = checkDate.split('/')[2];
// create new Date() object from split pieces
var strDateCheck = new Date(strYYYY,(strMM - 1),strDD);
// evaluate each piece of resulting date object against each corresponding piece of checkDate
if(((strDateCheck.getMonth() + 1) == strMM) && (strDateCheck.getDate() == strDD) && (strDateCheck.getFullYear() == strYYYY)) {
/* if you wish, add additional validation constraints here */
return true; // all three pieces match exactly
} else {
return false; // at least one piece did not match
}
}
}
Is there any way to get system short date format in JavaScript?
For example whether system's short date is in American format eg. m/d/Y or in european eg. d/m/Y
Please note:
This is not question about formatting date or calculating it based on geolocation, but about getting the format from the OS/system
After a pinch of research I concluded that technically it's not possible to get regional settings -and by this, date format- but you can do several other things. Pick one of these options:a) The already mentioned -and outdated- "toLocaleString()" function:
var myDate = new Date(1950, 01, 21, 22, 23, 24, 225);
var myDateFormat = myDate.toLocaleString();
alert (myDateFormat);
ISSUES:1) You can't "myDateFormat.replace" to get the date mask as month is not stored as "01", "02", etc in the string but as text instead, based on locale (like "February" in English but it's "Φεβρουάριος" in Greek and who knows what in e.g. Klingon).2) Different behavior on different browsers3) Different behavior on different OS and browser versions...b) Use the toISOString() function instead of toLocaleString(). You won't get the locale date mask but get a date from which you can tell where's which part of the date (ie where "month" or "day" is in that string). You can also work with getUTCDate(), getUTCMonth() and getUTCDay() functions. You still can't tell what date format the client uses, but can tell which Year/Month/Day/etc you work with when you grab a date; use the code above to test the functions I mentioned here to see what you can expect.c) Read
Inconsistent behavior of toLocaleString() in different browser article and use the (IMHO great) solution described there
for my case i used a custom date that i know what number is day, what is month and what is year so it can possible with a simple replace statement.
let customDate = new Date(2222, 11, 18);
let strDate = customDate.toLocaleDateString();
let format = strDate
.replace("12", "MM")
.replace("18", "DD")
.replace("2222", "yyyy");
It is not possible. You can get culture from user browser and use some js libraries to convert to correct date format. http://code.google.com/p/datejs/
I made a function to determine the client date format. The function determine
the date format separator, and also determine the 1st, 2nd and third part of
the date format.
getDateFormat(){
// initialize date value "31st January 2019"
var my_date = new Date(2019,0,31);
console.log(my_date.toLocaleDateString());
// Initialize variables
var separator="";
var first="";
var second="";
var third="";
var date_parts = [];
// get separator : "-", "/" or " ", format based on toLocaleDateString function
if (my_date.toLocaleDateString().split("-").length==3){
separator = " - ";
date_parts = my_date.toLocaleDateString().split("-");
}
if (my_date.toLocaleDateString().split("/").length == 3) {
separator = " / ";
date_parts = my_date.toLocaleDateString().split("/");
}
if (my_date.toLocaleDateString().split(" ").length == 3) {
separator = " ";
date_parts = my_date.toLocaleDateString().split(" ");
}
// get first part
if (date_parts[0]==2019){
first ="yyyy";
} else if (date_parts[0] == 31){
first = "dd";
} else{
if (date_parts[0].length<=2){
first ="mm";
}
else{
first="mmm";
}
}
// get second part
if (date_parts[1] == 2019) {
second = "yyyy";
} else if (date_parts[1] == 31) {
second = "dd";
} else {
if (date_parts[1].length <= 2) {
second = "mm";
}
else {
second = "mmm";
}
}
// get third part
if (date_parts[2] == 2019) {
third = "yyyy";
} else if (date_parts[2] == 31) {
third = "dd";
} else {
if (date_parts[2].length <= 2) {
third = "mm";
}
else {
third = "mmm";
}
}
// assembly
var format = first + separator + second + separator + third;
console.log(format);
return format;
}
I've created a workaround to determine which format the user's browser is using.
This is in C# but the logic is the same:
Here are the steps:
First try to convert the user's browser date into American format (mm-dd-yyyy). Convert.ToDateTime is using the American date format.
If that fails it means the user is using European format (dd-mm-yyyy).
However, this will only cover the day 13 to 31 because this is not a valid month.
If the conversion is successful, do another check to determine if the converted date is between the current UTC day + 1 day (to cover UTC+14) and current UTC day - 1 day (to cover UTC-12).
https://www.timeanddate.com/time/current-number-time-zones.html
If the converted date is out of the current date range, it means the user's browser is using European format (dd-mm-yyyy) and you can convert it to American format if you want.
string localeDateString = "01/11/2020"; // e.g. input is using European format (dd-mm-yyyy)
var localeDate = new DateTime();
try
{
localeDate = Convert.ToDateTime(localeDateString);
//var checkTheFormatOfDateInput = localeDate.ToLongDateString();
var currentDateTime = DateTime.UtcNow;
//var currentDateTime = Convert.ToDateTime("11/01/2020");
//var checkTheFormatOfCurrentDate = Convert.ToDateTime("11/01/2020").ToLongDateString();
var currentDateTimePositive = currentDateTime.AddDays(1);
var currentDateTimeNegative = currentDateTime.AddDays(-1);
var outOfCurrentDateRange = !(localeDate.Ticks > currentDateTimeNegative.Ticks && localeDate.Ticks < currentDateTimePositive.Ticks);
if (outOfCurrentDateRange)
{
localeDate = DateTime.ParseExact(localeDateString, "dd/MM/yyyy", CultureInfo.InvariantCulture);
}
}
catch
{
localeDate = DateTime.ParseExact(localeDateString, "dd/MM/yyyy", CultureInfo.InvariantCulture);
}
//var checkTheEndResultFormat = localeDate.ToLongDateString();
Below is the clean code wrapped in a method:
private DateTime ConvertAmericanOrEuropeanDateFormatToAmericanDateFormat(string localeDateString)
{
var localeDate = new DateTime();
try
{
localeDate = Convert.ToDateTime(localeDateString);
var currentDateTime = DateTime.UtcNow;
var currentDateTimePositive = currentDateTime.AddDays(1);
var currentDateTimeNegative = currentDateTime.AddDays(-1);
var outOfCurrentDateRange = !(localeDate.Ticks > currentDateTimeNegative.Ticks && localeDate.Ticks < currentDateTimePositive.Ticks);
if (outOfCurrentDateRange)
{
localeDate = DateTime.ParseExact(localeDateString, "dd/MM/yyyy", CultureInfo.InvariantCulture);
}
}
catch
{
localeDate = DateTime.ParseExact(localeDateString, "dd/MM/yyyy", CultureInfo.InvariantCulture);
}
return localeDate;
}
A very good but lengthy answer can here found here: https://stackoverflow.com/a/9893752/2484903
A shorter one here:
let customDate = new Date(2222, 3, 8);
let strDate = customDate.toLocaleDateString();
let format = strDate
.replace("04", "MM")
.replace("4", "M")
.replace("08", "dd")
.replace("8", "d")
.replace("2222", "yyyy")
.replace("22", "yy");
console.log(format);
We create a date object of a known date and then parse the outcome.
First we look for "04" (which corresponds to 3 from the date definition); that would be the two digit month format MM. If not found, it must be the single digit format M. Afterwards do the same for day and year.
It should do the job...
function getSystemDateLocale(){
let testDate = (new Date('2000-1-30')).toLocaleDateString()
if (testDate.substring(0,2) == '30') return 'EU'
else return 'US'
}
Use Date.CultureInfo.formatPatterns.shortDate
Could anyone please explain the below code to me?
For example, i would like to set Today's date to today (21st of November, 2012) and the end date to the 3rd of December.
The reason for this is because i want to loop through a list of items, determine whether they are in the "past", "present" or "future" and assign a class to them accordingly.
I hope this makes sense! Any help is greatly appreciated and much welcomed!
function daysTilDate(expiredate){
expiredate ="12/"+expiredate+"/2012";
var thisDay=new Date(expiredate);
var CurrentDate = new Date();
var thisYear=CurrentDate.getFullYear();
thisDay.getFullYear(thisYear);
var DayCount=(thisDay-CurrentDate)/(1000*60*60*24);
DayCount=Math.round(DayCount);
return DayCount;
}
You can simplify the method like below if you want to calculate the days to an expire date. Please note that if you don't specify a test date, it'll take the current date as the test date.
function daysTilData(expireDate, testDate) {
if(typeof testDate === "undefined"){
testDate = new Date(); // now
}
var diff = expireDate - testDate;
// minus value meaning expired days
return Math.round(diff/(1000*60*60*24));
}
alert(daysTilData(new Date("12/31/2012")));
// result 40
alert(daysTilData(new Date("12/31/2012"), new Date("1/12/2013")));
// result -12
Here's a line by line explanation.
The function declaration...
function daysTilDate(expiredate){
Takes the parameter expiredate sets it equal to the same value with "12/" prepended and "/2012" appended. so if the value of expiredate was "10", the new value is now "12/10/2012"...
expiredate ="12/"+expiredate+"/2012";
Instantiates a new Date object named thisDay using the expiredate string...
var thisDay=new Date(expiredate);
Instantiates a new Date object named CurrentDate, using the default constructor which will set the value equal to today's date...
var CurrentDate = new Date();
Gets just the Year segment from CurrentDate (which was earlier set to today's date)...
var thisYear=CurrentDate.getFullYear();
Gets the Year segment from thisDay (which was earlier set to "2012")...
thisDay.getFullYear(thisYear);
Gets the difference between thisDay and CurrentDate, which is in milliseconds, and multiplies that by 1000*60*60*24 to get the difference in days...
var DayCount=(thisDay-CurrentDate)/(1000*60*60*24);
Rounds the previously calculated difference...
DayCount=Math.round(DayCount);
Returns the difference between today and the passed-in day in December 2012...
return DayCount;
}
Note that the 2 lines that get the year segments are extraneous, because those values are never used...
I am not going to review the code, but I can answer your question of "I want to loop through a list of items, determine whether they are in the past, present, or future".
First, you want to construct your target date. If it's "now", just use new Date(). If it's a specific date, use new Date(dateString).
Second, Date objects in JavaScript have various members that return the date's characteristics. You can use this to compare dates. So, let's say you have your date strings in an array:
function loopDates(targetDateString, myDates) {
var targetDate, nextDate, status, ix;
targetDate = new Date(targetDateString);
for (ix = 0; ix < myDates.length; ++ix) {
nextDate = new Date(myDates[ix]);
if (nextDate.getFullYear() < targetDate.getFullYear()) {
status = "past";
} else if (nextDate.getFullYear() > targetDate.getFullYear()) {
status = "future";
} else {
// Year matches, compare month
if (nextDate.getMonth() < targetDate.getMonth()) {
status = "past";
} else if (nextDate.getMonth() > targetDate.getMonth()) {
status = "future";
} else {
// Month matches, compare day of month
if (nextDate.getDate() < targetDate.getDate()) {
status = "past";
} else if (nextDate.getDate() > targetDate.getDate()) {
status = "future";
} else {
// Day matches, present
status = "present";
}
}
}
console.log("Date " + myDates[ix] + " is " + status + " from " + targetDateString);
}
}
loopDates("11/17/2012", ["11/16/2012", "11/17/2012", "11/18/2012"]);
This will log:
Date 11/16/2012 is past from 11/17/2012
Date 11/17/2012 is present from 11/17/2012
Date 11/18/2012 is future from 11/17/2012
Working jsFiddle here.
If you want to work with a comprehensive Date class, use DateJS, an open source JavaScript date and time processing library with some impressive features.
How would I achieve the pseudo-code below in JavaScript? I want to include the date check in the second code excerpt, where txtDate is for the BilledDate.
If ABS(billeddate – getdate) > 31 then yesno “The date you have entered is more than a month from today, Are you sure the date is correct,”.
if (txtDate && txtDate.value == "")
{
txtDate.focus();
alert("Please enter a date in the 'Date' field.")
return false;
}
Generally speaking you work with Date-objects in javascript, and these should be constructed with the following syntax:
var myDate = new Date(yearno, monthno-1, dayno);
//you could put hour, minute, second and milliseconds in this too
Beware, the month-part is an index, so january is 0, february is 1 and december is 11 !-)
Then you can pull out anything you want, the .getTime() thing returns number of milliseconds since start of Unix-age, 1/1 1970 00:00, så this value you could subtract and then look if that value is greater than what you want:
//today (right now !-) can be constructed by an empty constructor
var today = new Date();
var olddate = new Date(2008,9,2);
var diff = today.getTime() - olddate.getTime();
var diffInDays = diff/(1000*60*60*24);//24 hours of 60 minutes of 60 second of 1000 milliseconds
alert(diffInDays);
This will return a decimal number, so probably you'll want to look at the integer-value:
alert(Math.floor(diffInDays));
To get the date difference in days in plain JavaScript, you can do it like this:
var billeddate = Date.parse("2008/10/27");
var getdate = Date.parse("2008/09/25");
var differenceInDays = (billeddate - getdate)/(1000*60*60*24)
However if you want to get more control in your date manipulation I suggest you to use a date library, I like DateJS, it's really good to parse and manipulate dates in many formats, and it's really syntactic sugar:
// What date is next thrusday?
Date.today().next().thursday();
//or
Date.parse('next thursday');
// Add 3 days to Today
Date.today().add(3).days();
// Is today Friday?
Date.today().is().friday();
// Number fun
(3).days().ago();
You can use this to check for valid date
function IsDate(testValue) {
var returnValue = false;
var testDate;
try {
testDate = new Date(testValue);
if (!isNaN(testDate)) {
returnValue = true;
}
else {
returnValue = false;
}
}
catch (e) {
returnValue = false;
}
return returnValue;
}
And this is how you can manipulate JS dates. You basically create a date object of now (getDate), add 31 days and compare it to the date entered
function IsMoreThan31Days(dateToTest) {
if(IsDate(futureDate)) {
var futureDateObj = new Date();
var enteredDateObj = new Date(dateToTest);
futureDateObj.setDate(futureDateObj.getDate() + 31); //sets to 31 days from now.
//adds hours and minutes to dateToTest so that the test for 31 days is more accurate.
enteredDateObj.setHours(futureDateObj.getHours());
enteredDateObj.setMinutes(futureDateObj.getMinutes() + 1);
if(enteredDateObj >= futureDateObj) {
return true;
}
else {
return false;
}
}
}
Hello and good day for everyone
You can try Refular Expressions to parse and validate a date format
here is an URL yoy can watch some samples and how to use
http://www.javascriptkit.com/jsref/regexp.shtml
A very very simple pattern would be: \d{2}/\d{2}/\d{4}
for MM/dd/yyyy or dd/MM/yyyy
With no more....
bye bye