Pete On Software

RSS Feed

Examining Moment.js

Moment.jsRecently, I was listening to the .Net Rocks! Podcast and Miguel Castro was on talking about MVVM for the web. I only mildly care about the topic, but I like to listen to things even outside of my normal sphere of interest to broaden my range of knowledge. Another side benefit is that sometimes you get unexpected gold nuggets thrown your way. This was one of those times.

Miguel was talking about some JavaScript libraries that were popular with his circle of friends/peers and he mentioned Moment.js. I had heard the name come up in the list of all of the {{noun}}.js libraries that were out there, but never really paid it any mind. All the while, I was suffering JavaScript date pain and I didn’t have to! ;)

To get started using it, you can either download it from the link above, or you can use npm, NuGet, or bower to install it.

bower install moment --save # bower
npm install moment --save   # npm
Install-Package Moment.js   # NuGet

From there, you can just reference it into your web page. Alternatively, you can just reference it from a CD and never do the install (//cdnjs.cloudflare.com/ajax/libs/moment.js/2.8.3/moment.js is one).

I’m starting out with this shell of a page. I made a div with the id of playground here I can write out output from Moment.js without using alerts all over the place. I’m going to wrap all of the calls to moment in the writeToPlayground method to get the output.

<html>
<head>
<title>Testing Moment.js</title>
</head>
<body>
<div id="playground"></div>

<script type="text/javascript" src="http://cdnjs.cloudflare.com/ajax/libs/moment.js/2.8.3/moment.js"></script>
<script type="text/javascript">
function writeToPlayground(val) {
	document.getElementById('playground').innerHTML += val + '<br />';
}
</script>
</body>
</html>

I have this shell – including all of the code in this post – as a jsfiddle that you can access at http://jsfiddle.net/PeteOnSoftware/pe4n383h/ to help make it all as clear as possible.

To get started with moment, you just have to create a moment object and then call the format or calendar methods.

writeToPlayground("moment().format() returns " + moment().format());
writeToPlayground("moment().calendar() returns " + moment().calendar());

This gives us:
moment().format() returns 2014-11-15T08:32:47-05:00
moment().calendar() returns Today at 8:32 AM

The format method takes a format string and gives us a lot of power

writeToPlayground("moment().format('dddd') returns " + moment().format('dddd'));
writeToPlayground("moment().format('MMMM') returns " + moment().format('MMMM'));
writeToPlayground("moment().format('MM/DD/YYYY, hh:mm:ss') returns " + moment().format('MM/DD/YYYY, hh:mm:ss'));

This outputs:
moment().format(‘dddd’) returns Saturday
moment().format(‘MMMM’) returns November
moment().format(‘MM/DD/YYYY, hh:mm:ss’) returns 11/15/2014, 08:32:47

But, this isn’t just about date formatting. It also does a lot of date manipulation for you. If you need to subtract time from a date, you can write

writeToPlayground("moment().subtract(10, 'minutes').format('MM/DD/YYYY, hh:mm:ss') returns " + moment().subtract(10, 'minutes').format('MM/DD/YYYY, hh:mm:ss'));

And that outputs: moment().subtract(10, ‘minutes’).format(‘MM/DD/YYYY, hh:mm:ss’) returns 11/15/2014, 08:22:47

But, better than ALL of those things is this next little beauty. If you use .Net as a REST API, whether through WCF or through WebApi, you are probably going to be used to seeing dates returned like this: /Date(1198908717056-0700)/. This is some tainted version of a JS date that doesn’t quite conform to standards that other people are using. If you try to deserialize it in JS, it fails, with or without the -0700 part. The issue is that JSON doesn’t specify a date format, so Microsoft returns *kind of* what you’d need to parse the date. The 1198908717056 part is the number of milliseconds since the Epoch and the -0700 part is supposed to be the timezone offset. Here are some examples of what would happen if you tried to just naively parse what you got back, or if you tried to parse it after doing some manipulation.

writeToPlayground("Trying to parse that as a new Date('/Date(1198908717056-0700)/') gives back " + new Date('/Date(1198908717056-0700)/'));
writeToPlayground("Trying to parse that as a new Date(1198908717056-0700) gives back " + new Date(1198908717056-0700));
writeToPlayground("Trying to parse that as a Date without the -700 as Date(1198908717056) gives back " + new Date(1198908717056));

Gives us:
Trying to parse that as a new Date(‘/Date(1198908717056-0700)/’) gives back Invalid Date
Trying to parse that as a new Date(1198908717056-0700) gives back Sat Dec 29 2007 01:11:56 GMT-0500 (EST)
Trying to parse that as a Date without the -700 as Date(1198908717056) gives back Sat Dec 29 2007 01:11:57 GMT-0500

I’ve run into these same problems trying to parse those kinds of values in Android and iOS applications, too. Here, in the second example, JavaScript just does the subtraction first, which is why the second result is about a second behind the third result (700 milliseconds).

However, Moment.js just takes that .Net value returned and handles it like a champ.

writeToPlayground("moment(/Date(1198908717056-0700)/).format('LLLL') returns " + moment(/Date(1198908717056-0700)/).format('LLLL'));

Brings back: moment(/Date(1198908717056-0700)/).format(‘LLLL’) returns Saturday, December 29, 2007 1:11 AM

That just makes my day! If you want to know more about Moment.js, go check out its page and documentation here. If you just want to play around, go check out my JSFiddle and mess with my examples or just enter sample dates into the textbox and click the PARSE button to see what Moment.js will do with your input.

Podcast Episode 27 – From Slangin Burgers to Slangin Code

McDonalds, Image licensed for reuseEpisode 27 finds me on a business trip and being a little introspective with this podcast. In this episode, I give my answers to two questions that I found on the web. First, “I work at McDonald’s but I want to be a professional programmer. Is it possible?” and Second, “What differentiates a programmer and a really good programmer? How is the code considered good or bad?”.


Links Mentioned in this Show:
Podcast Episode 15: Is College Worth It?
Dimecasts
NSScreencast
Watch Me Code
Pluralsight
Codecademy
Iris Classon
Stackshare

You can also subscribe to the podcast at any of these places:
iTunes Link RSS Feed Listen on Stitcher
In addition, my podcast is available on DoubleTwist and the Windows Marketplace.
Thanks to all the people who listen, and a special thanks to those who have rated me. I really appreciate it.
Listen here:

Winners and Losers

Gold Trophy, labeled for reuse from WikipediaI was listening to James Altucher’s interview with Shane Snow this morning and some of their discussion reminded me of something that Ron Carter (former podcast guest) is fond of saying. It is a quote that I try to remember and live by, so I thought that I’d share it here.

Winners take the blame when something goes wrong and give (or share) credit when things go right. Losers look to assign blame when things go wrong and hog the credit when things go right.

That’s applicable in so many areas of life. Think about the quarterback who goes before the press after a loss and says that he made the wrong read or that he has to play better when the real problem was that his receiver ran the wrong route or his offensive line was a sieve. However, on victory day that same quarterback is praising the offensive line’s protection and the play calling and the receivers’ exceptional skill.

That is the same model that we should seek to have. Don’t worry that you aren’t going to get your proper credit. If you did a great job, your teammates will know your role. And they won’t forget that you helped them shine, too. More than that, though, they’ll respect you for not throwing them under the bus when things go wrong.

This isn’t just about success and failure in a team environment. When a loser fails on solo endeavors, he’ll look to blame society, his equipment, the government, his family, his parents, whatever. Anything but turning the gaze inward and looking to see how the failure can be an opportunity to learn and grow and improve.

Winners take responsibility. Winners share credit. Winners learn from mistakes. Be a winner.

String Replace in JavaScript

Today, I had the need to do a String.Replace in JavaScript. I thought, “surely, this is an easily solved problem”. It turns out that I was both right and wrong.

A quick DuckDuckGo search brought back that I could do something like this:

var input = "I hate Fridays.  Fridays are the worst!";
var output = input.replace("Fridays", "Mondays");

I would expect the value of output to be “I hate Mondays. Mondays are the worst!”. But it isn’t. Instead, the value is “I hate Mondays. Fridays are the worst!”, because the replace method will only replace the first instance of the match.

The first solution that I found to this was to modify the code to use a regular expression, which the replace method also takes. All you have to do is include the RegEx and the “g” flag to make the replacement global. That would make the code look like this:

var input = "I hate Fridays.  Fridays are the worst!";
var output = input.replace(/Fridays/g, "Mondays");

This does give us the correct output of “I hate Mondays. Mondays are the worst!”, but if this were to be a reusable method or a pattern throughout an application, getting the correct RegEx can be tricky to debug or come back to later. Not everyone is a RegExpert. That’s why the next solution that I found was ingenious and was the one that I ended up going with.

In this code, you split the string on your “outgoing” string, and join it back together again with your “incoming” string. That would look like this:

var input = "I hate Fridays.  Fridays are the worst!";
var output = input.split("Fridays").join("Mondays");

That gives us our correct output of “I hate Mondays. Mondays are the worst!”. This method can be slower in some browsers (This JSPerf test has Split/Join as coming out ~40% slower in Chrome), but if you aren’t doing this several hundred times in a loop, I think the readability and maintainability of the Split/Join way makes this easy to do.

Podcast Episode 26 – Rondale Williams on Android and Breaking Into the Game

Rondale WilliamsThis time, in Episode 26, I interview Rondale Williams. Rondale is a freelance mobile developer new to the development space. During the course of our interview, Rondale talks about what it is like to be self-taught, why he started to go back to college for CS, and what his advice would be to other people just starting out. We also talk about RxJava, Android Emulators, the Android vs iOS development ecosystems, and whether or not he’s found the community to be friendly.



Links Mentioned in this Show:
Rondale’s Blog
Rondale’s Twitter
Rondale’s LinkedIn
RxJava
Genymotion
Lynda.com
Pluralsight
The New Boston (Bucky’s World)
Udemy
Udacity
Meetup
RemoteCoder.io

You can also subscribe to the podcast at any of these places:
iTunes Link RSS Feed Listen on Stitcher
In addition, my podcast is available on DoubleTwist and the Windows Marketplace.
Thanks to all the people who listen, and a special thanks to those who have rated me. I really appreciate it.
Listen here:

« Older Entries