JavaScript Date to Time

Subtle differences sometimes indicate the proficiency of a programmer.

Here are three ways to get the current time in JavaScript:

var t1 = (new Date()).getTime(); // 1
var t2 = new Date().getTime(); // 2
var t3 = (new Date).getTime(); // 3

The bracket placement is as much about language awareness as personal taste. In JavaScript, the brackets are optional for a zero-argument constructor: new Date creates a new Date instance without requiring brackets. But due to JavaScript operator precedence, you can’t write new Date.getTime() because the interpreter sees that as trying to call the constructor for a Date.getTime class (cf. MyPackage.MyClass) – in this case the brackets are required for the statement to parse as intended.

Reflecting on the three versions above: Version 1 doesn’t do anything to show a deep understanding of JavaScript. Version 2 and 3 are sort of interchangeable, but version 3 just edges ahead because the coder’s displayed knowledge to drop the optional brackets.

Of course, if you want the most compact code possible, you’d write:

var t4 = +new Date; // 4

This little gem creates a new Date, then coerces it into a number using a unary + operator – and coercing a Date to a number is defined in the language spec to go via valueOf and getTime.

Checking the character-count: (new Date).getTime() is 20 characters, while +new Date is 9.

That 11 character saving might come in handy on, say, the new Google home-page, where they currently use (new Date).getTime() seven times.

8 comments so far, add yours

AppleScript – a frustrating beginning

Academia and professional work has exposed me to a few different programming paradigms: functional, logical, procedural and object-orientated. I usually get along fine with a new paradigm, starting off with a few example programs and hacking away at them to get a decent grasp of the language. But, I’m not getting anywhere with AppleScript – it’s a frustrating beastie!

I think the root cause is the documentation. A quick read of wikipedia’s page on AppleScript shows you you’re dealing with a natural language. AppleScript statements read like english sentences with padding words like “the” being optional, for example: tell application "Finder" to say the name of the front Finder window as string.

Maybe I’m being mislead because I’m holding onto Tiger while waiting for Snow Leopard – I can’t see why you’d need to use as string at the end of the example given? A Finder window’s name property is documented as unicode text and yet I need to explicitly convert it to a string (or equivalently and for no good reason as text works too). It’s rubbish!

Accesing properties is a little odd too; I’m not even sure whether AppleScripts trying to be object-oreiented or not. We can rewrite the example to use a posessive 's instead of the of operator. e.g. tell app "Finder" to say front Finder window's name as text – which is nice. But sometimes it works, and sometimes it doesn’t. (note: I arbitrarily abbreviated application to app, but I’ve no idea where to find a full list of supported abbreviations…!)

I don’t grok the Script Editor at all. You can easily inspect the command, classes and properties supported by an application, but where the hell’s the core language documentation? Where do you go to find out – when it comes to strings – count is a method, but length is a property? count "some string" is OK, but count of "some string" isn’t! How do I find a list of all properties of the AppleScript class – or any other arbitrary class, record or structure?

In the days and weeks ahead I hope to progress to such advanced topics as:

  • writing arbitrary text to standard output (this doesn’t work and I’d like to write to standard output whenever I need to, not solely at the end of the program.)
  • checking a file exists (without using Finder or throwing an error)
  • list files in a directory (without using do shell script or using Finder)
  • get the urls of all tabs of all windows of safari (tell app "Safari" to get URL of every document only shows one URL per window, and my natural language instinct to use every document of every tab of every window falls flat on its face…)
  • access the /dev directory (POSIX file "/usr" as alias is fine, POSIX file "/dev" as alias throws an error! WTF!?)

To end on a semi-useful note, here are some very basic things I’ve discovered while developing AppleScript’s in a terminal window:

Determine AppleScript version number
$ osascript -e "AppleScript's version"
Show current track name from iTunes
(Note: I’m coming round to the idea that using $'...' is the best way of wrapping the applescript on a bash command-line – it allows you to backslash escape single-quotes and keep your double-quotes handy for literal strings.)
$ osascript -e $'tell application "iTunes" to get current track's name'

(you’d think there’d be more…)

I’ll follow up with another AppleScript article once I’ve mastered the art of controlling iTunes to extract artwork and iterate over albums and artists.

2 comments so far, add yours

All-in-one cookie function

Users stumbling across jQuery may notice the API’s designed so a method’s behaviour varies depending on the number and type of arguments passed in a call (have a look at the jQuery method!). In the right hands, this flexibility produces clean and elegant code without burdening the developer with 101 new method names to learn.

Let’s do the same for cookies (source: cookie.js).

Three into one does go

Googling for ‘javascript cookie functions‘ brings back Peter-Paul Koch’s trio of functions from QuirksMode. The functions are named setCookie, readCookie and eraseCookie. Browsing through the next few search-results we see the same thing going by different names: get, set and deleteCookie; add & remove, erase & delete, read, get and check – all variations on a theme, all separating functionality into a trio of functions.

Let’s look at the method signatures:

  • createCookie(name, value, days)
  • readCookie(name)
  • eraseCookie(name)

It’s pretty basic stuff.

To merge the three functions into one, we have to differentiate between reading, writing and deleting a cookie by the number and value of arguments; I’ve chosen an implementation where deleting a cookie is achieved by setting it to null.

Here’s some example usage:

  // create a cookie:
  cookie('name', 'value');

  // read it:
  alert(cookie('name'));

  // erase it:
  cookie('name', null);

Flexibility

All those cookie calls pass at least one parameter… but isn’t there something useful we can do with a plain parameterless cookie() call? Of course there is – let’s return an associative array of all cookie values!

By default (without specifying an explicit expiry time) cookies survive until you restart the browser. It’s kinda mandatory to provide some way of specifying an expiry time.

We’ll accept an optional third parameter specifying an expiry time in days:

  // create cookie for 1 year
  cookie('theme', 'minimal', 365);

  // grab all cookies:
  var cookies = cookie();
  alert(cookies.theme);

Looking good so far. But there’s more.

Like several of the cookie libraries, our function defaults to setting cookies on the top-level path “/” – this is a more common requirement than the browsers default behaviour, which sets a cookie so it’s only used at or below the current page level (i.e. a cookie set while looking at “/products/Nintendo-DSi-Console_Black/978372” wouldn’t be available when looking at any other product.)

To give developers flexibility I’ve made path another optional parameter – it could be used to share cookies between “/product/*” pages, but withhold them from any other area of a site.

While we’re on the subject of sharing – what about cross-domain cookies? Cookies are naturally assigned to the domain the page is being viewed on, but sometimes we want to make sure a cookie’s available to all sub-domains too. domain is also an optional parameter.

Having both path and domain as optional parameters could be confusing – after all, they’re both strings. Fortunately, we know paths begin with ‘/’ and domains don’t – and if you want to specify both you just stick to the right order: path then domain:

  // share cookie between product pages:
  cookie('view-description', 'hidden', '/products');

  // share cookie between domains:
  cookie('id', '_', '.ewelike.com');

  // save preferences cross-domain for 1 year:
  cookie('prefs', '_', 365, '/products', '.ewelike.com');

Finally, there’s an optional ‘secure’ parameter. I’ve never used this myself, but it’s there if you want it. It’s handy if you’re storing sensitive information in cookies and you only want to allow the browser to transfer the cookie value when it’s request pages via https. The code will take any truthy value hanging off the end of the parameters (anything that’s not been interpreted as expiry date, path or domain.):

  // set a secure cookie on the default path and domain
  // (expires when the browser closes)
  cookie('name', 'value', true);

Want the code? Grab it now… download cookie.js (dual-licensed under MIT and GPL, exactly the same as jQuery)

15 comments so far, add yours

The MacBook Pro’s not so bad…

Two years after moaning about my MacBook Pro I figure it’s time for an update:

It’s not so bad…

Thanks to various blog comments I managed to solve most of the niggles I had with the laptop:

muted the startup sound
This was pretty straight forward: download StartupSound.prefPane and choose the appropriate settings (I ticked the “Mute” box next to “Startup Volume” which seems to work fine.)
reconfigured keyboard layout using Ukulele
(definitely a personal preference) I configured a keyboard layout to match UK PC keyboards: backtick (`) to the left of 1, hash# and tilde~ next to return, at@ and double-quote” reversed (double-quote via Shift+2) and finally (I think) putting backslash and pipe| to the left of Z) If you want it, you can download my British PC keyboard layout (if I remember right, you have to move the file into /System/Library/Keyboard Layouts/ and may need to restart before you can choose it in System Preferences / International / Input Menu – and if you want a decent icon you’ll need the flag icon to bung in the Keyboard Layouts folder too.)

There is still one rather annoying aspect of the keyboard layout: it changes back to a Mac layout whenever I use Opera and tab into a password field – god knows what that’s all about!? I’ve got used to it now though and can quickly change back with Apple+Space

Better sleep & hibernate
Apple must have distributed a software update including fixes so waking up from sleep became a lot faster and more reliable. I’ve been months without shutting my Mac down, though I’ve recently changed my power settings so it goes into stand-by if I close the lid while plugged in, but goes into deep sleep if I close the lid while running off battery. What I’d really like is a way to say “go into stand-by for 15 minutes, then go into deep-sleep” – I think that’d be better when you’re running of battery and carting your computer from room to room – but want it to go into deep-sleep if you hit the motorway for 2 hours.
Region-free DVD
Hackers are great. About 8 months on from writing my bitch-post someone pointed out some a forum thread pointing to new firmware. Upgrading the firmware and installing Region X means I can actually view DVDs I paid for… (Is that a “w00t!” I hear at the back?)

It’s nice to have been pointed to solutions by readers, but there were a couple of physical issues readers couldn’t fix: the position of the drive slot, and the crappy return key.

( I realise I’m only one of a million voices shouting in the wind, but) Apple have redesigned the new MacBook Pros to put the DVD slot where it should be (on the side) and they’ve added an option to let you specify a US keyboard when you order a Mac online (giving chunky Return and Shift keys, and proper labelling to say META, ALT and OPTION)

I need to test-drive the new chicklet keyboard before deciding whether I’d be happy using a new MacBook Pro, but with the US keyboard layout and another region-free DVD hack, I think I’d quite happily upgrade. Of course Apple have made some changes that put me off too:

  1. you have to pay more for a matte display (it used to be the other way round: glossy screens cost more, but designers prefer matte displays for better colour accuracy, so Apple made the most common and desirable option the one that costs a premium. That’s business!)
  2. unremovable battery. On some days that doesn’t sound so bad: the pro (long battery life) outweighs the con (high one-off replacement cost after 3-4 years.) But… I’ve been through the experience of defective batteries: my original MBP battery got burning hot and buckled over the course of a few months. I’d hate to think what would happen if the battery was wrapped around the PCB and pushing against all edges of a one-piece case.
  3. non-upgradeable memory. Well, kinda. This is a consequence of a non-removable battery – the option to upgrade from 4 to 8GB looks like it has to be done at the point of ordering, and for a hefty charge. Then again… 4GB of memory ought to be just fine, and (if it really comes down to it) I’m sure there’ll be a 32-step upgrade guide to replace the memory modules as soon as a memory supplier begins to sell them.

All in all, I’m pretty happy with my MacBook Pro these days. I get on better with OS X then Windows for a couple of reasons. I prefer Apple subtle nudge reminding you there’s a monthly / bi-monthly software update ready to install – compare that to Microsoft’s randomly timed “I’m gonna restart your computer in 5 minutes” auto-upgrade annoyance (and yes, I’m well aware of “net stop wuauserv” to stop the nagging – I can’t remember how many times I’ve had to type that in.) Plus, the BSD / *nix nature of OS X allows me to setup a development environment that behaves much closer to our live CentOS servers than Cygwin on Windows does.

I bought a Mac Mini last summer while rumours of a new revision were reaching fever pitch – I’m glad I didn’t wait. The Mini’s been an absolute pleasure – running damn-near silently and without issues. But that’s wandering off track.

I do have a new hate though: Sky HD. Compared to my recently deceased TiVo, SkyHD is one of the most incompetent PVRs I’ve ever had the displeasure of using. The only reason I haven’t cancelled my Sky subscription completely is because (as far as I know) there’s no other way to get Sky 1 – and I do like Lost, 24, Battlestar Gallactica and all the big American productions that come to Sky first…

And now I’m really off track. Sky HD’s a gripe for another day…

Leave the first comment

Concatenating arrays in PHP

Just a quick post so I know where to look the next time I forget how to concatenate arrays in PHP.

Use array_merge to concatenate two numerically-indexed arrays; not array_push and not the array union operator: +.


$first = array('doh', 'ray', 'me');
$second = array('fah', 'soh', 'lah', 'te', 'do');

echo "Union: ", var_export($first + $second, true), "n";
echo "Merge: ", var_export(array_merge($first, $second), true), "n";

// array_push returns int, not an array:
array_push($first, $second);
echo "Push: ", var_export($first, true), "n";

The output:

Union: array (
  0 => 'doh',
  1 => 'ray',
  2 => 'me',
  3 => 'te',
  4 => 'do',
)
Merge: array (
  0 => 'doh',
  1 => 'ray',
  2 => 'me',
  3 => 'fah',
  4 => 'soh',
  5 => 'lah',
  6 => 'te',
  7 => 'do',
)
Push: array (
  0 => 'doh',
  1 => 'ray',
  2 => 'me',
  3 => 
  array (
    0 => 'fah',
    1 => 'soh',
    2 => 'lah',
    3 => 'te',
    4 => 'do',
  ),
)
8 comments so far, add yours