moment.js change format based on difference - javascript

I want to follow the same structure as content posting websites where new posts follow something like:
(seconds/minutes/hours ago), (yesterday), (days ago), (MMM Do YY).
How would I rearrange the JS to follow this format and go to (MMM Do YY) after say, 3 days?
// iterates over every element with the .js-time-ago css class
$('.date').each(function() {
var $this = $(this),
textDate = $this.data('date'), // gets the date from the date attribute
postedDate = moment(textDate, ['DDMMMMY', 'MMMMDDY']).format(), // formats the date in a formate that will continue to be supported by Moment JS
today = moment().format(), // gets today's date
timeSince = moment(today, 'YYYY-MM-DD').diff(moment(postedDate, 'YYYY-MM-DD'), 'days'); // sets up the dates to be compared so that we can get a number for if statement below
if (timeSince >= 0) $this.text(moment(postedDate).fromNow());
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.13.0/moment.min.js"></script>
<div class="date" data-date="01 April 2018"></div>
<div class="date " data-date="26 May 2018"></div>
<div class="date" data-date="27 May 2018"></div>

We can acheive what you want by doing two things to your code first passing ing 'day' into the moment().diff() function to get the difference in days then checking that value is smaller than 3 using a ternary statement very similar to an if.
I've cleaned up the code abit to show the 5 steps i'm taking
Storing the time now outside the loop
get the date from the attribute
get the difference in days
format the date based on if its less than 3 days
appending that value to the element
function formatDate() {
const NOW = new Date();
$('.date').each(function() {
const DATE = new Date($(this).data('date'));
const DIFF = moment(NOW).diff(DATE, 'day');
const FORMAT = DIFF < 3 ?
moment(DATE).fromNow() :
moment(DATE).format('MMM Do YY');
$(this).text(FORMAT);
});
}
formatDate()
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.13.0/moment.min.js"></script>
<div class="date" data-date="01 April 2018"></div>
<div class="date " data-date="26 May 2018"></div>
<div class="date" data-date="27 May 2018"></div>

You're actually really close - you just need to implement the conditional logic based on timeSince being within the range you want, in your example 3 days.
If you simply switch your if statement with a ternary (or even an IF-ELSE) that checks to see if the timeSince value is less than or equal to 3, you can achieve the desired result. Here's the ternary statement to use in place of your current if one:
(timeSince <= 3) ? $this.text(moment(postedDate).fromNow()) : $this.text(moment(postedDate).format('MMM Do YY'));
The ternary/conditional statement first takes a condition to evaluate - in your case, whether or not timeSince is less than or equal to 3 days ago. If the condition is true, the first expression is executed - in this case, formatting the value from your .date selector using Moment's x ago format. If the condition is false, meaning more than 3 days ago in this example, it uses Moment to format the text using the MMM Do YY format.
Complete CodePen example here: https://codepen.io/anon/pen/zjgbmp
For an example of how a ternary helps keeps your code concise, here's the same solution using IF-ELSE:
if (timeSince <= 3) {
$this.text(moment(postedDate).fromNow());
}
else {
$this.text(moment(postedDate).format('MMM Do YY'));
}

Related

Get Date from HTML Element and compare it to Today's Date JS

I have only just started coding in javascript so I have not got everything learned down pat.
I would like to reference a date in an element on an HTML page and use javascript to alert the user that the Date is in the past.
Here is what I have so far:
var EndDate = document.getElementById("Close");
document.getElementById("AuctionDate").innerHTML =
Date.parse(EndDate.innerHTML);
var TodaysDate = Date.parse(Date());
document.getElementById("TodaysDate").innerHTML = TodaysDate;
if (EndDate < TodaysDate) {
alert("Closed");
} else {
alert("Open");
}
<span id="Close">27 September 2017</span>
<p id="AuctionDate"></p>
<p id="TodaysDate"></p>
I've converted today's date into a number and shown it to see if it worked.
I can't seem to figure out how to compare them properly as I could not find out how to make the EndDate parse.
Thanks.
As you currently have it, you're grabbing the .innerHTML from Close, and assigning that straight to EndDate. This value (27 September 2017) is then compared against the current timestamp (1506645355000). Strings are compared lexicographically, so JavaScript thinks that the string of 27 September 2017 is 'larger' than the integer 1506645355000.
What you need to do is move your Date.parse() to the first line, wrapping your Date.parse() in the variable assignment itself, so that your variable EndDate ends up with the parsed date.
Then, if required, you can output this back to the page by setting the target .innerHTML of AuctionDate to the variable EndDate directly:
var EndDate = Date.parse(document.getElementById("Close").innerHTML);
console.log("EndDate's value is: " + EndDate) // returns a parsed date
document.getElementById("AuctionDate").innerHTML = EndDate;
var TodaysDate = Date.parse(Date());
document.getElementById("TodaysDate").innerHTML = TodaysDate;
if (EndDate < TodaysDate) {
alert("Closed");
} else {
alert("Open");
}
<span id="Close">27 September 2017</span>
<p id="AuctionDate"></p>
<p id="TodaysDate"></p>
Hope this helps! :)
Try this:
if (new Date('27 September 2017') < new Date('28 September 2017')) {
console.log('still open')
}
// where
// 27 September 2017 is dateToday
// 28 September 2017 is dateCloses
var today = document.getElementById("TodaysDate").innerHTML
var dateToday = new Date(today)
Your original var EndDate = document.getElementById("Close"); is just getting the DOM element where you have put your date.
So your subsequent comparison if (EndDate < TodaysDate) is comparing a DOM Element < Date Object
You can get the date from your Close html element by selecting the element and then getting the text within it:
var dateString = document.getElementById('Close').innerText
Since you want to deal with Date objects, you can then parse it:
var EndDate = Date.parse(dateString)
At this point you can compare the two Date objects.
Note also, there is no point parsing a Date object:
var TodaysDate = Date.parse(Date());
You can simply do
var TodaysDate = new Date();
I know they don't look the same, but you really want to deal with Date objects throughout.
Side note: you should usually use .innerText rather than .innerHTML
Take this example -- say that instead of this
<span id="Close">27 Septermber 2017</span>
you had a more complex structure:
<span id="Close"><span class="day">27</span> <span class="month">September</span> <span class="year">2017</span></span>
In this case, close.innerHtml would give you that whole mess
<span id="Close"><span class="day">27</span> <span class="month">September</span> <span class="year">2017</span></span>
but close.innerText would give just 27 September 2017
Whether you want innerText or innerHTML depends on what you're actually do with what you've got; know the difference and know which you want.

Compare one date with today using DD-MM-YYYY format

I want to compare a date (mydate) with today. I tried
new Date(mydate) < new Date();
which works in all cases apart from the case my date equals today. In that case the above returns true since it compares the time included. However, I want to compare only the date, not the time.
I tried moment.js as well:
moment(mydate).format('DD-MM-YYYY')<moment().format('DD-MM-YYYY')
however, not even this one did work. What do I have to write?
You can use moment function isSame and provide the second argument as the granularity level you want for your comparison. The granularity levels can be strings like, 'year', 'month', 'day'
moment('2010-01-01').isSame('2010-02-01', 'day');
You can also look into similar functions documented over there which might help you better with your requirement.
Is Before
Is Same
Is After
Is Same or Before
Is Same or After
Is Between
All of these supports different granularity levels.
As a sidenote, to create a date in your supplied format do:
moment("25-12-1995", "DD-MM-YYYY");
You can simply do following using moment js
$(document).ready(function() {
$('.compare').click(function(e) {
var date = $('#date').val();
var now = moment().format('YYYY-MM-DD');
var then = moment(date).format('YYYY-MM-DD');
if (now > then) {
$('.result').text('Date is past');
} else if(now == then) {
$('.result').text('Date is today');
} else {
$('.result').text('Date is future');
}
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.10.3/moment.min.js"></script>
<input type="text" name="date" id="date" value="2014-12-18" placeholder="yyyy-mm-dd">
<button class="compare">Compare date to current date</button>
<br>
<div class="result"></div>

Momentjs - Get most recent Friday

I'm trying to get the start of (12:00am, or, 00:00am) of the most recent Friday. This has been working:
moment().isoWeekday(5).startOf('day').toDate()
But it only works Friday->Sunday, on Monday morning it will then refer to the upcoming Friday, in which case this would work:
moment().add('-1', 'week').day(5).startOf('day').toDate()
but I need it be dynamic and done in one line if possible, to where I don't to perform any checks on the current day.
Is there a way to always get the most recent Friday? Regardless of what the current day is.
Edit I'm also trying to get this to return the current day (friday) if executed on a Friday.
If you don't want to use a library, it's pretty straight forward
var date = new Date();
while ( date.getDay() !== 5 ) date.setDate(date.getDate() -1);
console.log(date)
With moment
var date = moment();
var friday = date.day(date.day() >= 5 ? 5 :-2);
and if millisecond accuracy doesn't matter, you could call moment() twice to make it one line (but I would much raher use a variable)
var friday = moment().day(moment().day() >= 5 ? 5 :-2);
Check this:
var date = moment().utc().isoWeekday(5);
if(moment().day() < 5) {
date = date.add(-1, 'week');
}
console.log('Recent friday starts:', date.startOf('day').toDate());
console.log('Recent friday ends:', date.endOf('day').toDate());
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.15.1/moment.js"></script>

PHP, javascript, jquery, setting hour only

I have created a small function that i need on my site successfully in php. But i now realise i actually need this in javascript or jquery as PHP will only excute this code on load.. i need this function to work with onchange on a select. The code below is my function.. Can anyone point out where i start to convert this into js/jquery like code:
function setTrnTime ($hr, $journeyTime){
date_default_timezone_set('GMT');
//convert current hour to time format hour
$currentHour = (date("H", mktime($hr)));
// Journey time in hours
$journey = $journeyTime
$journey = $journey/60; // Get hours
$journey = ceil($journey); // Round off to next hour i.e. 3 hours 20mins is now 4 hours
// New Hours
$NewHour = (date("H", mktime($journey)));
$Newhour = $NewHour*60*60; // convert to seconds
// Final hour is Current Hour - JourneyTime (Hours)
$trnHour = (date('H', mktime($currentHour-$NewHour)));
return $trnHour;
}
With the code above, if i pass two values 06, 60: that would mean my answer would be 05. e.g. 06 is 6am. 60 is 60mins.. so 6am - 60mins = 5am.
You can do the same in javascript using the Date object, see info here
https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Date
EDITED: Added some code, also not even using the Date object.
But do you need something that complex, doesn't the following do what you are after with less steps.
http://jsfiddle.net/WWTDc/
If hr is a Date object, then it's very simple. Otherwise you can create a Date object and set its hour:
//! \param[in] hr Date object or hour (0--23)
//! \param[in] journeyTime journey time in minutes.
function setTrnTime(hr,journeyTime){
var end;
if(typeof(hr) === 'number'){
end = new Date();
end.setHours(hr);
}
else
end = hr;
return (new Date(end - journeyTime*60*1000)).getHours();
}
This will return the hour (demonstration).
See here for information about Date object in JavaScript.

the closest Sunday before given date with JavaScript

I need to know the date for last Sunday for given date in php & javascript
Let's have a function give_me_last_Sunday
give_me_last_Sunday('20110517') is 20110515
give_me_last_Sunday('20110604') is 20110529
The full backup is done on Sundays = weekly. If I want to restore daily backup I need full (weekly) and daily backup. I need to copy backup files before restoring to temp directory so I restoring daily backup I need to know what weekly backup file I need to copy along the daily file.
My thought was to get Julian representation (or something similar) for the given date and then subtract 1 and check if it is Sunday ... Not sure if this is the best idea and how to convert given date into something I can subtract.
Based on Thomas' effort, and provided the input string is exactly the format you specified, then:
function lastSunday(d) {
var d = d.replace(/(^\d{4})(\d{2})(\d{2}$)/,'$1/$2/$3');
d = new Date(d);
d.setDate(d.getDate() - d.getDay());
return d;
}
Edit
If I were to write that now, I'd not depend on the Date object parsing the string but do it myself:
function lastSunday(s) {
var d = new Date(s.substring(0,4), s.substring(4,6) - 1, s.substring(6));
d.setDate(d.getDate() - d.getDay());
return d;
}
While the format yyyy/mm/dd is parsed correctly by all browsers I've tested, I think it's more robust to stick to basic methods. Particularly when they are likely more efficient.
Ok so this is for JavaScript only. You have an input that you need to extract the month, date, and year from. The following is just partly an answer then on how to get the date:
<script type="text/javascript">
var myDate=new Date();
myDate.setFullYear(2011,4,16)
var a = myDate.getDate();
var t = myDate.getDay();
var r = a - t;
document.write("The date last Sunday was " + r);
</script>
So the setFullYear function sets the myDate to the date specified where the first four digits is the year, the next are is the month (0= Jan, 1= Feb.,...). The last one is the actually date. Then the above code gives you the date of the Sunday before that. I am guessing that you can add more code to get the month (use getMonth() method). Here are a few links that might be helpful
http://www.w3schools.com/js/js_obj_date.asp
http://www.w3schools.com/jsref/jsref_setFullYear.asp
http://www.w3schools.com/jsref/jsref_getMonth.asp
(You can probably find the other functions that you need)
I hope this helps a bit even though it is not a complete answer.
Yup and strtotime has been ported to JS for eg http://phpjs.org/functions/strtotime:554 here.
final code (big thanks to #Thomas & #Rob)
function lastSunday(d) {
var d = d.replace(/(^\d{4})(\d{2})(\d{2}$)/,'$1/$2/$3');
d = new Date(d);
d.setDate(d.getDate() - d.getDay());
year = d.getFullYear()+'';
month = d.getMonth()+1+'';
day = d.getDate()+'';
if ( month.length == 1 ) month = "0" + month; // Add leading zeros to month and date if required
if ( day.length == 1 ) day = "0" + day;
return year+month+day;
}

Categories

Resources