Adding setUTCDate() to replace "computers" time - javascript

I followed this tutorial, but I wanted to just be able to set a date and have it countdown to that date.
Even so, it would just base it off my computer's time; how can I make it so it's standard for everyone?
He mentioned setUTCDate() but I have no idea how to implement it?

Here's some code to get you started. It gets the UTC time and alert's it, formatted:
// By default, JS does not pad times with zeros
function checkTime(i) {
if(i<10) i='0'+i;
return i;
}
// Set current UTC time
var d = new Date();
var now = checkTime(d.getUTCHours()) + ':' +
checkTime(d.getUTCMinutes()) + ':' +
checkTime(d.getUTCSeconds());
// Output
alert(now);
Here's a JSFiddle.
Remember: UTC != GMT (read on if you want this to always match the UK time).
BST (when the clocks go forward) will need to be factored in for anyone in the UK wanting to use this solution.
Here's a function I wrote earlier:
// Function returning 0 or 1 depending on whether BST is in effect
function isBSTinEffect()
{
var d = new Date();
// Loop over the 31 days of March for the current year
for(var i=31; i>0; i--)
{
var tmp = new Date(d.getFullYear(), 2, i);
if(tmp.getDay() == 0) { lSoM = tmp; break; }
}
// Loop over the 31 days of October for the current year
for(var i=31; i>0; i--)
{
var tmp = new Date(d.getFullYear(), 9, i);
if(tmp.getDay() == 0) { lSoO = tmp; break; }
}
if(d < lSoM || d > lSoO) return 0;
else return 1;
}
To factor in BST, put that function before // Set current UTC time and change checkTime(d.getUTCHours()) to checkTime(d.getUTCHours()+isBSTinEffect())

Related

Get all days of the week given a day

I'm trying to make a function to get all the days of the week given the current day. I had a function that i thought was working until i noticed that if the day of the week is near the end of the month, like for example February, i get weird data. Anyone know whats going on and how to fix it?
function days(current) {
var week = new Array();
// Starting Monday not Sunday
var first = ((current.getDate() - current.getDay()) + 1);
for (var i = 0; i < 7; i++) {
week.push(
new Date(current.setDate(first++))
);
}
return week;
}
var input = new Date(2017, 1, 27);
console.log('input: %s', input);
var result = days(input);
console.log(result.map(d => d.toString()));
.as-console-wrapper{min-height:100%}
If you don't want to use some kind of other library like Moment.js you can also change your function a little and then it will work. Try this:
function dates(current) {
var week= new Array();
// Starting Monday not Sunday
current.setDate((current.getDate() - current.getDay() +1));
for (var i = 0; i < 7; i++) {
week.push(
new Date(current)
);
current.setDate(current.getDate() +1);
}
return week;
}
console.log(dates(new Date(2017, 1, 27)));
You can use Moment.js library - utility library for dates/time operations
Here's examplary code to get current week's dates starting from monday:
function getThisWeekDates() {
var weekDates= [];
for (var i = 1; i <= 7; i++) {
weekDates.push(moment().day(i));
}
return weekDates;
}
var thisWeekDates = getThisWeekDates();
thisWeekDates.forEach(function(date){ console.log(date.format());});
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.22.2/moment.js"></script>
The code above prints following results to the console:
2017-03-20T21:26:27+01:00
2017-03-21T21:26:27+01:00
2017-03-22T21:26:27+01:00
2017-03-23T21:26:27+01:00
2017-03-24T21:26:27+01:00
2017-03-25T21:26:27+01:00
2017-03-26T21:26:27+02:00
I will trace your code using your example of Feb 27, 2017:
first = 27 - 1 + 1 = 27
loop:
Feb.setDate(27) = 27 feb
Feb.setDate(28) = 28 feb
Feb.setDate(29) = Not 29 days in Feb. So it sets current to 29-28 = 1st day of March
March.setDate(30) = March 30
March.setDate(31) = March 31
March.setDate(32) = Not 32 days in March. So it sets current to 31-32 = 1st of April..
April.setDate(33) = Not 33 days in April. So it sets current day 33-30 = 3rd day of May.
Please note that I used the shorthand of Month.setDate() to show the month of the current Date object when it was being called.
So the issue is with your understanding of setDate that is being used on current. It changes the month and if the value you use isn't a day in the month it adjusts the month and day appropriately. I hope this cleared things up for you.
For how to add one to a date, see Add +1 to current date. Adapted to your code, you can set current to the first day of the week then just keep adding 1 day and pushing copies to the array:
function days(current) {
var week = [];
// Starting Monday not Sunday
var first = current.getDate() - current.getDay() + 1;
current.setDate(first);
for (var i = 0; i < 7; i++) {
week.push(new Date(+current));
current.setDate(current.getDate()+1);
}
return week;
}
var input = new Date(2017, 1, 27);
console.log('input: %s', input);
var result = days(input);
console.log(result.map(d => d.toString()));
Note that this changes the date passed in (per the original code), you may want to make current a copy to avoid that.
Suppose monday starts the week, you can calculate monday and go to sunday. getDategives you the day of the week, and Sunday starts at 0. With momnday, we get just offset forward to 6 days to get sunday
mondayThisWeek(date: Date): Date {
const d = new Date(date)
const day = d.getDay()
const diff = d.getDate() - day + (day === 0 ? -6 : 1)
return new Date(d.setDate(diff))
}
const offsetDate = (base: Date, count: number): Date => {
const date = new Date(base)
date.setDate(base.getDate() + count)
return date
}
thisWeek(today: Date): TimeRange {
const monday = mondayThisWeek(today)
return {
startDate: monday,
endDate: offsetDate(monday, 6)
}
}
This can be achieved easly using moment
const getWeekDates = () => {
let weekDates = [];
for (let i = 0; i < 7; i++)
weekDates.push(moment().add(i, 'd'));
return weekDates;
};
console.log(getWeekDates());
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.22.2/moment.js"></script>

What is the correct way to achieve this Javascript loop?

I'm working on a calendar using PHP to get my dates from a server and Javascript to do the front end math. From the server I'm using the following values to work with: Today's date, number of days in current month, and today's position in the week with reference to a Sun to Sat 0-6 convention. In order to find the first day of a given month, I have to work backwards from the current day which has known values.
The chart below shows what I'm trying to do with Javascript. A switch is when I change the pos variable back to 6(7 due to for loop problem) when I've hit 0 as I'm subtracting away from pos.
The problem is that when the for loop starts, the position of today's current day which is 5, is immediately subtracted by 1, when it shouldn't be until the next day which is 28 (previous).
By inserting delays (see the initialPos variable), I'm able to get the right value. This doesn't seem right, what is the right way to do this?
Here's a comparison of the outputs with and without delays.
With delay:
Without delay:
(without delay means I didn't add 1 to todayPositionWeek, and 7 is 6 for the reset pos counter)
<script>
today = 29;
todayPositionWeek = 5;
// start the count with todayPositionWeek shifted by 1 to not count
var initialPos = todayPositionWeek+1;
var numSwitches = 0;
var loopRan = 0;
for (var i = today; i > 0; i--) {
loopRan++;
// initialPos is 6
initialPos--;
// after it is 5 on first run
if(initialPos == 0) {
// reset pos counter
initialPos = 7;
// initially this was set to 6 but skips to 5
numSwitches++;
}
firstDayPos = initialPos;
}
alert('loop ended ' + firstDayPos + ' ' + numSwitches + ' ' + loopRan);
</script>
Today it's fine, but if the day is off(today is not on Friday), the shifted days are off...
var today = 27;
var todayPositionWeek=3;
var offset = (toDayPositionWeek+7-(today%7))%7 // ==4 because day0 ==4
function posOfAnyDay(d) {
return (offset + d) % 7;
}
function slotOfAnyDay(d) {
return Math.floor((offset + d) / 7);
}
// posOfAnyDay(13) -> 3
// slotOfAnyDay(13) -> 2
for (var i = today; i > 0; i--) {
pos = posOfAnyDay(i);
slot = slotOfAnyDay(i);
}

How to get the 7 days in a week with a currentDate in javascript?

(first, sorry for my bad english, i'm a beginner)
I have a chart of percent by date. I would like to display every day of the current week in the x-axis.
So, i tried to find how to get the seven days of the week.
that's what i have :
var curr = new Date; // get current date
var first = curr.getDate() - curr.getDay();//to set first day on monday, not on sunday, first+1 :
var firstday = (new Date(curr.setDate(first+1))).toString();
for(var i = 1;i<7;i++){
var next = first + i;
var nextday = (new Date(curr.setDate(next))).toString();
alert(nextday);
}
the alert begins well...until the end of the month. That's what i got :
1 : "Mon 27 Feb 2012 ..."
2 : "Tue 28 Feb 2012 ..."
3 : "Wed 29 Feb 2012 ..."
4 : "Thu 01 Mar 2012 ..."
5 : "Sat 31 Mar 2012 ..."
6 : "Sun 01 Apr 2012 ..."
So, as you can see, it switches the friday and... strangely it switch to the good date...4 weeks later...
So, do you have a better solution for me, or maybe you could just help me and say what is the problem.
Thank you!
I'm afraid you have fallen into one of the numerous traps of object mutation. :)
The problem is that, in the line "var nextday = ...", you are changing the date saved in "curr" on every iteration by calling setDate(). That is no problem as long as next is within the range of the current month; curr.setDate(next) is equivalent to going forward one in this case.
The problems begin when next reaches 30. There is no February 30, so setDate() wraps around to the next month, yielding the 1st of March - so far so good. Unfortunately, the next iteration calls curr.setDate(31), and as curr is the 1st of March (remember that the object referenced by curr is changed in each iteration), we get... March 31! The other strange values can be explained the same way.
A way to fix this is to copy curr on each iteration and then call setDate(), like so:
for (var i = 1; i < 7; i++) {
var next = new Date(curr.getTime());
next.setDate(first + i);
alert(next.toString());
}
Thank you all,
I understood that everytime i change the curr value and that was the problem.
All your solutions are working, but i'll prefer the simplest one, the one from #denisw, which I copy there for anybody else with the same problem :
var curr = new Date; // get current date
var first = curr.getDate() - curr.getDay();
var firstday = (new Date(curr.setDate(first+1))).toString();
for(var i = 1; i < 7; i++) {
var next = new Date(curr.getTime());
next.setDate(first+i);
alert(next.toString());
}
Once again, thank you all, for your quick answers and your help!
You can add date and day. The former goes from 1 to 28..31 and the latter from 0 to 6. What should the Date type do if you set the date to -3?
The solution is to convert all values to milliseconds.
var ONE_DAY_IN_MILLIS = 1000*60*60*24;
var curr = new Date();
// Get offset to first day of week
// Note: Depending on your locale, 0 can be Sunday or Monday.
var offset = curr.getDay() * ONE_DAY_IN_MILLIS;
// Date at the start of week; note that hours, minutes and seconds are != 0
var start = new Date( curr.getTime() - offset );
for( var i=0; i<7; i++ ) {
var nextDay = new Date( start.getTime() + ( i * ONE_DAY_IN_MILLIS ) );
...
}
The problem is that you are modifying your curr date and creating a new date at the same time. There are two ways to do this:
Either never modifiy your curr date object and create new Dates:
var msInDay = 1000 * 60 * 60 * 24;
function addDays(date, days) {
return new Date(date.getTime() + days * msInDay);
}
var curr = new Date();
var first = addDays(curr, -curr.getDay() + 1);
alert(first);
for(var i = 1; i<7; i++) {
var next = addDays(first, i);
alert(next);
}
Or modify your curr date object consistently:
var curr = new Date();
curr.setDate(curr.getDate() - curr.getDay() + 1);
alert(curr);
for(var i = 1; i<7; i++) {
curr.setDate(curr.getDate() + 1);
alert(curr);
}
​
let curr = new Date;
let week = []
for (let i = 1; i <= 7; i++) {
let first = curr.getDate() - curr.getDay() + i
let day = new Date(curr.setDate(first)).toISOString().slice(0, 10)
week.push(day)
}
console.log('week:', week);
jsfidde: https://jsfiddle.net/sinh_nguyen/v9kszn2h/4/

How to detect the user's locale date and time format

Is there a possibility to determine, with pure Javascript, what date time FORMAT has user configured on his operating system (Windows, Linux, MAC OS, etc.)?
Thanks in advance.
EDIT: I know about the method toLocaleString(), but this isn't help me to get the format that client has configured on his local machine.
I wrote something in pure javascript that works in IE/Firefox/Chrome. It will out put MM/DD/YYYY or DD/MM/YYYY,... depending in toLocalDateString().
Did not work on Safari but new Date().toLocalDateString() did not either.
Here is a jsFiddle
//Create a known date string
var y = new Date(2013, 9, 25);
var lds = y.toLocaleDateString();
//search for the position of the year, day, and month
var yPosi = lds.search("2013");
var dPosi = lds.search("25");
var mPosi = lds.search("10");
//Sometimes the month is displayed by the month name so guess where it is
if(mPosi == -1)
{
mPosi = lds.search("9");
if(mPosi == -1)
{
//if the year and day are not first then maybe month is first
if(yPosi != 0 && dPosi != 0)
{
mPosi = 0;
}
//if year and day are not last then maybe month is last
else if((yPosi+4 < lds.length) && (dPosi+2 < lds.length)){
mPosi = Infinity;
}
//otherwist is in the middle
else if(yPosi < dPosi){
mPosi = ((dPosi - yPosi)/2) + yPosi;
}else if(dPosi < yPosi){
mPosi = ((yPosi - dPosi)/2) + dPosi;
}
}
}
var formatString="";
var order = [yPosi, dPosi, mPosi];
order.sort(function(a,b){return a-b});
for(i=0; i < order.length; i++)
{
if(order[i] == yPosi)
{
formatString += "YYYY/";
}else if(order[i] == dPosi){
formatString += "DD/";
}else if(order[i] == mPosi){
formatString += "MM/";
}
}
formatString = formatString.substring(0, formatString.length-1);
$('#timeformat').html(formatString+" "+lds);
Here's an idea, that may or may not work.
Create a date where all the elements are distinct, like February 18th 1999 at 13:45, use toLocaleString(), then identify the elements based on their distinct values.
Could be kind of complicated and I don't have any code that might help with it, but it's an idea to be thrown out there, maybe you can make use of it.
EDIT: Here's some code:
var d = new Date(1999,1,18,13,45,0).toLocaleString();
document.write("<p>String: "+d+"</p>");
var f = d
.replace(/1999/,"%Y")
.replace(/99/,"%y")
.replace(/F[^ ]{3,}/i,"%M")
.replace(/F[^ ]+/i,"%m")
.replace(/PM/,"%A")
.replace(/pm/,"%a")
.replace(/18[^ ]+/,"%d%S") // day number with suffix
.replace(/18/,"%d")
.replace(/13/,"%H")
.replace(/1/,"%h")
.replace(/45/,"%i")
.replace(/00/,"%s");
// optionally add something to detect the day of the week (Thursday, here)
document.write("<p>Format: "+f+"</p>");
Output:
String: 18 February 1999 13:45:00
Format: %d %M %Y %H:%i:%s
Something like this ?
<script type="text/javascript">
var d=new Date();
document.write("Original form: ");
document.write(d + "<br />");
document.write("Formatted form: ");
document.write(d.toLocaleString());
//calculate change of the 2 dates
</script>

Strange Javascript Problem Involving split("/");

Okay, so using the following function:
function date_add(date, days)
{
var dim = {1:31, 2:28, 3:31, 4:30, 5:31, 6:30, 7:31, 8:31, 9:30, 10:31, 11:30, 12:31};
console.log(date.split("/"));
var date_arr = date.split("/");
console.log(date_arr);
...
}
I get the following output at the console screen for date_add("12/08/1990", 1)
["12", "08", "1990"]
["2", "08", "1990"]
Spending an hour struggling with what could fix this weird problem, on a whim I changed my function to the following:
function date_add(date, days)
{
var dim = {1:31, 2:28, 3:31, 4:30, 5:31, 6:30, 7:31, 8:31, 9:30, 10:31, 11:30, 12:31};
date = date.split("/");
console.log(date);
...
}
Magically, the code works again. Now don't get me wrong, I'm ecstatic that it worked. I'm seriously concerned over why it worked, though, when the other didn't. More or less I'm just concerned with why the other didn't work. Does anyone have a good explanation?
Edit: Now they're both broken. >.>
For Tomas, here is the full function:
function date_add(date, days)
{
var dim = {1:31, 2:28, 3:31, 4:30, 5:31, 6:30, 7:31, 8:31, 9:30, 10:31, 11:30, 12:31};
console.log(date);
console.log(date.split("/"));
date_arr = date.split("/");
console.log(date)
if (date_arr[0][0] = "0") date_arr[0] = date_arr[0][1];
if (date_arr[1][0] = "0") date_arr[1] = date_arr[1][1];
var month = parseInt(date_arr[0]);
var day = parseInt(date_arr[1]);
var year = parseInt(date_arr[2]);
console.log(month);
console.log(day);
console.log(year);
if ((year%4 == 0 && year%100 != 0) || year%400 == 0)
dim[2] = 29;
day += days;
while (day < 1)
{
month--;
if (month < 1)
{
month = 12;
year--;
}
day += dim[month];
}
while (dim[month] < day)
{
day -= (dim[month]+1);
month++;
if (month > 12)
{
month = 0;
year++;
}
}
return ""+month+"/"+day+"/"+year;
}
As for the input for the function, I called this function from the console using date_add('12/08/1990',1);
The problem with your original code is most probably you were not using the second parameter for your parseInt() calls, which is to specify the base for which you want to convert to, by default it assumes a 10 base, but when the number starts with zero as in your 08 case, then it assumes its an octal number, so the solution is to use the second parameter in your parseInt calls, like this:
var month = parseInt(date_arr[0], 10);
var day = parseInt(date_arr[1], 10);
var year = parseInt(date_arr[2], 10);
This behaviour have been fixed in last versions of javascript (EcmaScript 5), see this question for more info:
How do I work around JavaScript's parseInt octal behavior?

Categories

Resources