3.2 Dates and Loops
# JavaScript Date Objects
If you were writing HTML then you could add a <time>
element and write a string that represents a Date. However, this
would not be an object that you could use in your script. JavaScript comes with a Date
object that you can actually
manipulate, convert to different times, calculate time differences, and work with just the time or just the date value.
There is a new Temporal
object that is under development. It will give us a lot more control over things like time
zones, time ranges, and international formatting. Until that happens, we still have a basic Date
object that we can
use for all our basic needs.
There are actually a few different ways that you can call the Date
constructor method.
let today = new Date(); //create a Date object with the current time and date from your computer.
let date1 = new Date('28/9/2016 14:30:00.000'); //a formatted string
let date2 = new Date(2016, 9, 28, 14, 30, 0); // yyyy, mm, dd, hours, mins, seconds
let date3 = new Date(1500000000000); //a timestamp with the number of milliseconds since Jan 1 1970, 12am
2
3
4
The first line above will create a new Date object and it will fill it with the current date and time from the computer that is running the script.
The second line creates a new Date object and sets a specific date and time. We pass in a String with a valid date and
time. The values for day, month, year, hour, minutes, seconds, and milliseconds would be set inside our Date object. The
String that is passed in must be a date string that would be recognized by the Date.parse( )
method. See
here for examples (opens new window)
The third line accepts up to seven arguments for the parts of the Date. The last argument is the milliseconds. dt2 will contain the same date as dt1 from the example code.
The last line accepts a timestamp, which is the number of milliseconds since the start of the Unix Epoch -> Jan 1, 1970 00:00:00.000Z. In July of 2017 we passed the 1.5 Trillion mark for milliseconds in the current timestamp. You can pass any number to this method to set the time and date inside the Date object.
# Setting Date Values
If you want to update any part of the date or time then we use one of the following methods.
today.setHours(12); // from 0-23. OR setHours(hour, mins, seconds, milliseconds)
today.setMinutes(3); // from 0-59. OR setMinutes(mins, seconds, milliseconds)
today.setSeconds(50); // from 0 - 59 OR setSeconds(seconds, milliseconds)
today.setMilliseconds(123); // from 0 - 999
today.setFullYear(2044);
today.setMonth(0); //value from 0 - 11 (like an array) OR setMonth( month, day)
today.setDate(); //value from 1 - 31 invalid dates will move forward to a valid one
Date.UTC(y, m, d, hr, min, sec, ms); //creates a date object and returns the timestamp
//equivalent of the date
2
3
4
5
6
7
8
9
10
# Retrieving Date Values
If you want to retrieve any part of the date or time then you can use the matching "get" methods. Start with using your Date variable and then call the method on the variable
today.getHours();
today.getMinutes();
today.getSeconds();
today.getMilliseconds();
today.getFullYear();
today.getMonth(); // value from 0 - 11
today.getDate(); // value from 1 - 31
today.getDay(); //day of week Sunday (0) - Saturday (6)
Date.now(); //Using the Date object, call now( ) to get a timestamp
//which is the number of milliseconds since the start of the UNIX Epoch
//midnight January 1, 1970
2
3
4
5
6
7
8
9
10
11
12
# Outputting Dates
There are many methods for outputting the date object's value. Here is a list of the various methods.
today.toDateString(); //returns the date portion in human readable format
today.toTimeString(); //returns the time portion in human readable format
2
MDN toDateString reference (opens new window)
MDN toTimeString reeference (opens new window)
today.toISOString(); //returns a string in simplified extended ISO format
MDN toISOString reference (opens new window)
today.toJSON(); //converts the date to a string intended to be used in JSON
MDN toJSON reference (opens new window)
today.toLocaleDateString('en-CA'); //returns a string representation based on the
//computer's locale settings or provided locale
today.toLocaleString('en-GB'); //same thing effectively
today.toLocaleString('en-US');
2
3
4
MDN toLocaleDateString (opens new window)
MDN toLocaleString (opens new window)
today.toUTCString(); //returns the date string using UTC time zone
MDN toUTCString reference (opens new window)
# Working With Months
In the JavaScript Date object, months are stored as a number between 0 and 11.
If you want to see or use the name of the month then you need to create your own array of the month names and use the Date object month as the index for that array.
let months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Sep', 'Oct', 'Nov', 'Dec'];
let today = new Date();
console.log('Current month is:', months[today.getMonths()]);
2
3
# Converting to Timestamps (unary)
The unary +
operator is an easy way to convert a date into its numeric timestamp.
let today = new Date();
let timestamp = +today; //convert the value in the date to a timestamp
let timestamp = +new Date(); //convert the current computer time to a timestamp
let timestamp = Date.now(); //use the Prototype/Class/Static method
let timestamp = today.valueOf(); //get the timestamp of a specific date
2
3
4
5
MDN Date object reference (opens new window)
# Moment.JS Library
If you are building something that works with a lot of dates or times then it can help to have a JavaScript library that you can use. MomentJS is a great JS library http://momentjs.com/ (opens new window) for formatting and validating dates.
# Luxon Time and Date Library
There is a new updated version of MomentJS, built by one of the team members from MomentJS, called Luxon. It incorporates the latest browser support for multilingual and timezone operations.
Both the
Moment.JS
andLuxon
libraries will be redundant once the newTemporal
time and date Object becomes standardized.
# Loops
A loop is a very common programming structure. It is actually part of the control-flow category that we discussed last week.
The purpose of a loop is to repeat one or more commands, as quickly as possible, a specific number of times or until a condition is met.
First, lets review why we have loops. They are a common feature in programming languages. Say, for example, that you
wanted to create a list of five random numbers. You could declare five variables and use the Math.random( )
method to
generate the numbers and assign them to the variables. We could do this with just repeating the same line of code five
times.
let num1 = Math.random();
let num2 = Math.random();
let num3 = Math.random();
let num4 = Math.random();
let num5 = Math.random();
2
3
4
5
While a bit tedious, you can do this without too much effort.
Now, imagine that you need to save a thousand random numbers, or ten thousand. That would be a LOT of code to write. Loops are a programmatic way of accomplishing a similar task in a repetitive manner with minimal code. Here is an example that would generate 100,000 random numbers and save them all in an Array.
let nums = [];
for (let i = 0; i < 100000; i++) {
nums.push(Math.random());
}
2
3
4
That's it. Four lines of code. 100,000 random numbers generated and saved in an Array. An Array is a numbered list. We will talk about them in detail next week.
Array objects also have built-in methods for looping over all the items inside them. We will talk about those and use them a lot over the next few semesters. The loops discussed on this page can be used with Arrays as well as pretty much any time you need to do something repeatedly.
# For loops
The example above is the standard for
loop. The code inside the parentheses is split into three parts. The three parts
are divided by semi-colons. ;
- Initialization. Declare local variables for the loop. Usually just a variable that can be used to count the number of iterations of the loop. Commonly known as the counter variable. This part runs before any looping begins. You can declare as many variables as you want here, separating each declaration with a comma.
- Test condition. Normally this means comparing your counter variable to a maximum or minimum value. The loop will run this test once before each iteration of the loop.
- Increment/Decrement. Every time the loop finishes running the commands that are inside the curly braces, this part of the code runs. It runs after the commands and before the next test.
For loops are the most common type of loop. They can be used for practically any situation that needs a loop because they are flexible.
# For in Loop
A second type of for loop is the for...in
loop. These are used to loop through a list of items that have a known
number of items. They work with Objects that are iterable
. We will talk more about this in the future. For now, just
think of it as a short hand way to loop through an Array.
for (let prop in myArray) {
// output each value in the Array, one at a time.
console.log(myArray[prop]);
}
2
3
4
We will not use these very often but it is good to be familiar with them.
# For of Loop
These are closely related to for...in loops but let you target the value without having to use dot notation or the square bracket syntax. If you don't need the index number of the array or the property name from the object then this might be of value to you.
There is a difference between for...in
and for...of
in that for...of
cannot loop over most Objects. This has to do
with the difference between Iterable
and Enumerable
, which we will talk about later.
For those of you who are keen to understand this now:
# While Loop
There are two kinds of while loops in JavaScript, the while loop and the do..while loop. The difference between them is that the do..while loop will always run at least once because it runs the loop before checking to see if the while test passes. The while loop will test your condition before it runs the loop.
var counter = 0;
while (counter < 10) {
console.log(counter);
counter++;
}
var counter2 = 0;
do {
console.log(counter2);
counter2++;
} while (counter2 < 10);
2
3
4
5
6
7
8
9
10
11
MDN while loop ref (opens new window)
# Infinite Loops
When using while
loops you do need to be careful that you don't create an infinite loop condition. That is a loop that
never ends. When this happens your code can quickly use up all the system resources and even make the browser crash.
While modern browsers are pretty good at avoiding the crash part, it will still result in your code ceasing to run.
Consider the code example below. That loop will never end. The value of isRunning
will always be true
.
let i = 0;
let isRunning = true;
while (isRunning) {
console.log(i);
i++;
}
2
3
4
5
6
7
We need some test condition to make the loop stop running. Inside the loop we can test the value of i
and if it
exceeds a desired value then we can change the value of isRunning
.
while (isRunning) {
console.log(i); //output the value of i
i++; //increment the value of i
if (i > 100) {
isRunning = false;
}
}
2
3
4
5
6
7
Now the next check that while(isRunning)
does will exit the loop.
What about times when we can't change the value of the test condition?
Thankfully there is a keyword - break
which can be used to immediately exit a loop (or switch
statement).
const shouldStart = true;
//pretend that shouldRun was declared elsewhere and passed to the function.
//and we have no way to change it's value.
while (shouldStart) {
console.log(i); //output the value of i
i++; //increment the value of i
if (i > 100) {
break; //immediately exit the loop before the next check of shouldStart
}
}
2
3
4
5
6
7
8
9
10
# Do While loop
There is one other variant of the while
loop called do while
.
do {
console.log(i); //output the value of i
i++; //increment the value of i
} while (i < 100);
2
3
4
Looks pretty much the same as the original while
loop, right?
The difference is that the do while
loop will ALWAYS run at least once. The test condition does not run until
after the loop. The while
loop does the test before starting.
# What to do this week
TODO Things to do before next week.
- Read all the content from
Modules 3.1, 3.2, and 4.1
. - Continue working on the Hybrid Exercises
- Submit Hybrid 2