Commits

Matthew Schinckel committed d11ddd8

Partial implementation of python style date handling

Comments (0)

Files changed (4)

js/dateExtensions.js

+Date.prototype.getWeek = function() { 
+    // ISO 8601 WkNo. m=1..12
+    var y,m,d;
+    y = this.getFullYear();
+    m = this.getMonth() + 1;
+    d = this.getDate();
+    var ms1d = 864e5, ms7d = 7*ms1d;
+    var DC3 = Date.UTC(y, m-1, d+3)/ms1d; // an Absolute Day Number
+    var DoW = 1 + (DC3+7777777)%7;
+    var AWN = Math.floor(DC3/7); // an Absolute Week Number
+    var Wyr = new Date(AWN*ms7d).getUTCFullYear();
+    var w = (AWN - Math.floor(Date.UTC(Wyr, 0, 7)/ms7d)+1);
+    return w;
+};
+
+Date.prototype.setWeek = function(value){
+    var offset = this.getDay();
+    this.setDate(3);
+    this.setMonth(0);
+    this.setDate(3 - this.getDay() + (value - 1)*7 + +offset);
+    return this;
+};
+
+Date.prototype.getDayOfYear = function(){
+    var day1 = new Date(this.getFullYear(), 0, 1);
+    return Math.ceil((this - day1)/864e5);
+};
+
+Date.prototype.setDayOfYear = function(value) {
+    this.setMonth(0);
+    this.setDate(value);
+    return this;
+};
+
+Date.prototype.strptime = function(date, format){
+    // If no format, use the following rules:
+    //      If a W is present, use %Y-W%U-%j
+    //      Try the format %Y-%m-%d
+    
+    if (!format) {
+        if (date.matches(/W/)) {
+            format = "%Y-W%U-%j";
+        } else {
+            format = "%Y-%m-%d";
+        }
+    }
+    
+    formats = {
+        // Ignore those that are irrelevant?
+        a: function(){},
+        A: function(){},
+        B: function(value){
+            for (fullName in this.months) {
+                if (fullName.slice(0,3) == value){
+                    this.setMonth(this.months.indexOf(fullName));
+                }
+            }
+        },
+        b: function(value){
+            this.setMonth(this.months.indexOf(value));
+        },
+        c: function(value){this.parse(value);},
+        d: function(value){this.setDate(value);},
+        f: function(value){this.setMilliseconds(value/1000);},
+        H: function(value){this.setHours(value);},
+        I: function(value){this.setHours(value);},
+        j: function(value){this.setDayOfYear(value);},
+        m: function(value){this.setMonth(value - 1);},
+        M: function(value){this.setMinutes(value);},
+        p: function(value){
+            if (value.matches(/pm/i)) {
+                this.setHours(this.getHours + 12);
+            }
+        },
+        S: function(value){this.setSeconds(value)},
+        U: function(value){this.setWeek(value)},
+        w: function(value){this.setDay(value)},
+        W: function(value){this.setWeek(value, "Monday")},
+        x: function(value){this.parse(value)},
+        X: function(value){this.parse(value)}
+    };
+};
+
+Date.prototype.strftime = function(format){
+    function zeroPad(value, length) {
+        value = "" + value;
+        while (value.length < length) {
+            value = "0" + value;
+        }
+        return value;
+    }
+    
+    var formats = {
+        a: this.getDayName().slice(0,3),
+        A: this.getDayName(),
+        b: this.getMonthName().slice(0,3),
+        //c: this.format("%x %X"),
+        c: this.toLocaleString(),
+        B: this.getMonthName(),
+        d: zeroPad(this.getDate(), 2),
+        f: this.getMilliseconds() * 1000,
+        H: this.getHours(),
+        I: zeroPad(this.getHours() % 12 > 0 ? this.getHours() : 12, 2),
+        j: this.getDayOfYear(),
+        m: zeroPad(this.getMonth() + 1, 2),
+        p: this.getHours < 12 ? "AM" : "PM",
+        S: this.getSeconds(),
+        U: this.getWeek(),
+        w: this.getDay(),
+        W: this.getWeek("Monday"),
+        // x: this.format("%Y-%m-%d"),
+        x: this.toLocaleDateString(),
+        // X: this.format("%H:%M:%S"),
+        X: this.toLocaleTimeString(),
+        y: zeroPad(this.getYear(),2),
+        Y: this.getFullYear(),
+        z: (this.getTimezoneOffset() > 0 ? "+" : "-") + 
+           zeroPad(parseInt(-this.getTimezoneOffset() / 60, 10), 2) +
+           zeroPad(-this.getTimezoneOffset() % 60, 2)
+    };
+    
+    return format.replace(/%(.)/g, function(_,v){return formats[v];});
+};
+
+Date.prototype.months = ["January","February","March","April","May","June",
+    "July","August","September","October","November","December"];
+    
+Date.prototype.getMonthName = function() {
+    return this.months[this.getMonth()];
+};
+
+Date.prototype.days = ["Sunday", "Monday", "Tuesday", "Wednesday",
+    "Thursday", "Friday", "Saturday", "Sunday"]; // Not a mistake, in twice.
+
+Date.prototype.getDayName = function() {
+    return this.days[this.getDay()];
+};
  */
  
 function datepicker(field) {
-  months = ["January","February","March","April","May","June",
-    "July","August","September","October","November","December"];
+  
   data = "<div id='datepicker' class='datepicker'>" +
             "<header>" +
                 "<div class='prev' />" +
   dp.attr('date', field.val());
   
   function parseDate(isoDate){
+    // If the isoDate contains a W, then it is a week-date.
+    if (isoDate.match(/W/)) {
+        
+    }
     var d = new Date();
     var date = isoDate.split('-');
     d.setFullYear(date[0]);
     d.setMonth(date[1]-1);
-    d.setDate(date[2]);
+    if (date[2]) {
+        d.setDate(date[2]);
+    } else {
+        d.setDate(1);
+    }
     return d;
   }
   
+
+
+
   function redraw(){
     // Redraw the datepicker, with the month that needs to be drawn.
     var d = new Date();
   };
   
   function returnDate() {
-    field.val(dp.attr('date'));
+    var type = field.attr('type');
+    if (type == "date") {
+        field.val(dp.attr('date'));
+    }
+    if (type == "week") {
+        field.val(weekFor(dp.attr('date')));
+    }
+    if (type == "month") {
+        field.val(dp.attr('date').slice(0,7));
+    }
     cancel();
   };
   
     dp.attr('date', date);
     returnDate();
   };
+  
   function selectToday() {
     dp.attr('date', new Date().toISOString().split('T')[0]);
     returnDate();
 
 
 $(function(){
-  $('input[type="date"], input[type="week"]').click(
+  $('[type="date"], [type="month"], [type="week"]').click(
     function(e){
       datepicker($(this));
       e.stopPropagation();
     %h3 Datepicker
     %h2 Datepicker fields
     %input{:type=>:date}
-      input type=date
-      %br
+    input type='date'
+    %br
     %input{:type=>:month}
+    input type='month'
+    %br
     %input{:type=>:week}
+    input type='week'
+    %br
     %input{:type=>:time}
+    input type='time'
+    %br
     %input{:type=>:datetime}
+    input type='datetime'
+    %br
     %input{:type=>"datetime-local"}
-    
+    input type='datetime-local'
+    %br
     %h2 Datepicker inline
 
         
     <input placeholder='Enter website address' type='url' />
     <h3>Datepicker</h3>
     <h2>Datepicker fields</h2>
-    <input type='date'>
-      input type=date
-      <br />
-    </input>
+    <input type='date' />
+    input type='date'
+    <br />
     <input type='month' />
+    input type='month'
+    <br />
     <input type='week' />
+    input type='week'
+    <br />
     <input type='time' />
+    input type='time'
+    <br />
     <input type='datetime' />
+    input type='datetime'
+    <br />
     <input type='datetime-local' />
+    input type='datetime-local'
+    <br />
     <h2>Datepicker inline</h2>
     <h3>Search</h3>
     <input placeholder='Google' type='search' />