sugar-rails 1.2.5 → 1.2.5.1
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +23 -1
- data/lib/sugar/rails/version.rb +1 -1
- data/vendor/assets/javascripts/sugar-core.js +4001 -0
- data/vendor/assets/javascripts/sugar-dates-only.js +3121 -0
- data/vendor/assets/javascripts/sugar-dates.js +2210 -0
- data/vendor/assets/javascripts/sugar-inflections.js +520 -0
- data/vendor/assets/javascripts/sugar.js +6211 -114
- metadata +8 -4
@@ -0,0 +1,2210 @@
|
|
1
|
+
// Google Closure Compiler will output a wrapping function here.
|
2
|
+
(function() {
|
3
|
+
|
4
|
+
// A few optimizations for Google Closure Compiler will save us a couple kb in the release script.
|
5
|
+
var regexp = RegExp, object = Object, date = Date, number = Number, Undefined, English;
|
6
|
+
|
7
|
+
function isDefined(o) {
|
8
|
+
return o !== Undefined;
|
9
|
+
}
|
10
|
+
|
11
|
+
function isUndefined(o) {
|
12
|
+
return o === Undefined;
|
13
|
+
}
|
14
|
+
|
15
|
+
|
16
|
+
/***
|
17
|
+
* Date module
|
18
|
+
*
|
19
|
+
***/
|
20
|
+
|
21
|
+
var TimeFormat = ['hour','minute','second','meridian','utc','offset_sign','offset_hours','offset_minutes']
|
22
|
+
var FloatReg = '\\d{1,2}(?:[,.]\\d+)?';
|
23
|
+
var RequiredTime = '('+FloatReg+'):?('+FloatReg+')?:?('+FloatReg+')?(am|pm)?(?:(Z)|(?:([+-])(\\d{2})(?::?(\\d{2}))?)?)?';
|
24
|
+
var OptionalTime = '\\s*(?:(?:t|at |\\s+)' + RequiredTime + ')?';
|
25
|
+
|
26
|
+
var LowerAsianDigits = '一二三四五六七八九';
|
27
|
+
var UpperAsianDigits = '十百千万';
|
28
|
+
var AsianDigitReg = regexp('[' + LowerAsianDigits + UpperAsianDigits + ']', 'g');
|
29
|
+
var DateInputFormats = [];
|
30
|
+
var DateArgumentUnits;
|
31
|
+
var DateUnitsReversed;
|
32
|
+
|
33
|
+
var StaticInputFormats = [
|
34
|
+
// @date_format 2010
|
35
|
+
{ src: '(\\d{4})', to: ['year'] },
|
36
|
+
// @date_format 2010-05
|
37
|
+
// @date_format 2010.05
|
38
|
+
// @date_format 2010/05
|
39
|
+
// @date_format 2010-05-25 (ISO8601)
|
40
|
+
// @date_format 2010-05-25T12:30:40.299Z (ISO8601)
|
41
|
+
// @date_format 2010-05-25T12:30:40.299+01:00 (ISO8601)
|
42
|
+
// @date_format 2010.05.25
|
43
|
+
// @date_format 2010/05/25
|
44
|
+
{ src: '([+-])?(\\d{4})[-.]?({month})[-.]?(\\d{1,2})?', to: ['year_sign','year','month','date'] },
|
45
|
+
// @date_format 05-25
|
46
|
+
// @date_format 05/25
|
47
|
+
// @date_format 05.25
|
48
|
+
// @date_format 05-25-2010
|
49
|
+
// @date_format 05/25/2010
|
50
|
+
// @date_format 05.25.2010
|
51
|
+
{ src: '(\\d{1,2})[-.\\/]({month})[-.\\/]?(\\d{2,4})?', to: ['month','date','year'], variant: true },
|
52
|
+
// @date_format Date(628318530718)
|
53
|
+
{ src: '\\/Date\\((\\d+(?:\\+\\d{4})?)\\)\\/', to: ['timestamp'], time: false }
|
54
|
+
];
|
55
|
+
|
56
|
+
var DateOutputFormats = [
|
57
|
+
{
|
58
|
+
token: 'f{1,4}|ms|milliseconds',
|
59
|
+
format: function(d) {
|
60
|
+
return d.getMilliseconds();
|
61
|
+
}
|
62
|
+
},
|
63
|
+
{
|
64
|
+
token: 'ss?|seconds',
|
65
|
+
format: function(d, len) {
|
66
|
+
return d.getSeconds();
|
67
|
+
}
|
68
|
+
},
|
69
|
+
{
|
70
|
+
token: 'mm?|minutes',
|
71
|
+
format: function(d, len) {
|
72
|
+
return d.getMinutes();
|
73
|
+
}
|
74
|
+
},
|
75
|
+
{
|
76
|
+
token: 'hh?|hours|12hr',
|
77
|
+
format: function(d) {
|
78
|
+
return getShortHour(d);
|
79
|
+
}
|
80
|
+
},
|
81
|
+
{
|
82
|
+
token: 'HH?|24hr',
|
83
|
+
format: function(d) {
|
84
|
+
return d.getHours();
|
85
|
+
}
|
86
|
+
},
|
87
|
+
{
|
88
|
+
token: 'dd?|date|day',
|
89
|
+
format: function(d) {
|
90
|
+
return d.getDate();
|
91
|
+
}
|
92
|
+
},
|
93
|
+
{
|
94
|
+
token: 'dow|weekday',
|
95
|
+
word: true,
|
96
|
+
format: function(d, loc, n, t) {
|
97
|
+
return loc['weekdays'][d.getDay() + (n - 1) * 7];
|
98
|
+
}
|
99
|
+
},
|
100
|
+
{
|
101
|
+
token: 'MM?',
|
102
|
+
format: function(d) {
|
103
|
+
return d.getMonth() + 1;
|
104
|
+
}
|
105
|
+
},
|
106
|
+
{
|
107
|
+
token: 'mon|month',
|
108
|
+
word: true,
|
109
|
+
format: function(d, loc, n, len) {
|
110
|
+
return loc['months'][d.getMonth() + (n - 1) * 12];
|
111
|
+
}
|
112
|
+
},
|
113
|
+
{
|
114
|
+
token: 'y{2,4}|year',
|
115
|
+
format: function(d) {
|
116
|
+
return d.getFullYear();
|
117
|
+
}
|
118
|
+
},
|
119
|
+
{
|
120
|
+
token: '[Tt]{1,2}',
|
121
|
+
format: function(d, loc, n, format) {
|
122
|
+
var m = getMeridian(d);
|
123
|
+
if(format.length === 1) m = m.first();
|
124
|
+
if(format.first() === 'T') m = m.toUpperCase();
|
125
|
+
return m;
|
126
|
+
}
|
127
|
+
},
|
128
|
+
{
|
129
|
+
token: 'z{1,4}|tz|timezone',
|
130
|
+
text: true,
|
131
|
+
format: function(d, loc, n, format) {
|
132
|
+
var tz = d.getUTCOffset();
|
133
|
+
if(format == 'z' || format == 'zz') {
|
134
|
+
tz = tz.replace(/(\d{2})(\d{2})/, function(f,h,m) {
|
135
|
+
return h.toNumber().pad(format.length);
|
136
|
+
});
|
137
|
+
}
|
138
|
+
return tz;
|
139
|
+
}
|
140
|
+
},
|
141
|
+
{
|
142
|
+
token: 'iso(tz|timezone)',
|
143
|
+
format: function(d) {
|
144
|
+
return d.getUTCOffset(true);
|
145
|
+
}
|
146
|
+
},
|
147
|
+
{
|
148
|
+
token: 'ord',
|
149
|
+
format: function(d) {
|
150
|
+
return d.getDate().ordinalize();
|
151
|
+
}
|
152
|
+
}
|
153
|
+
];
|
154
|
+
|
155
|
+
var DateUnits = [
|
156
|
+
{
|
157
|
+
unit: 'year',
|
158
|
+
method: 'FullYear',
|
159
|
+
multiplier: function(d) {
|
160
|
+
var adjust = d ? (d.isLeapYear() ? 1 : 0) : 0.25;
|
161
|
+
return (365 + adjust) * 24 * 60 * 60 * 1000;
|
162
|
+
}
|
163
|
+
},
|
164
|
+
{
|
165
|
+
unit: 'month',
|
166
|
+
method: 'Month',
|
167
|
+
multiplier: function(d, ms) {
|
168
|
+
var days = 30.4375, inMonth;
|
169
|
+
if(d) {
|
170
|
+
inMonth = d.daysInMonth();
|
171
|
+
if(ms <= inMonth.days()) {
|
172
|
+
days = inMonth;
|
173
|
+
}
|
174
|
+
}
|
175
|
+
return days * 24 * 60 * 60 * 1000;
|
176
|
+
}
|
177
|
+
},
|
178
|
+
{
|
179
|
+
unit: 'week',
|
180
|
+
method: 'Week',
|
181
|
+
multiplier: function() {
|
182
|
+
return 7 * 24 * 60 * 60 * 1000;
|
183
|
+
}
|
184
|
+
},
|
185
|
+
{
|
186
|
+
unit: 'day',
|
187
|
+
method: 'Date',
|
188
|
+
multiplier: function() {
|
189
|
+
return 24 * 60 * 60 * 1000;
|
190
|
+
}
|
191
|
+
},
|
192
|
+
{
|
193
|
+
unit: 'hour',
|
194
|
+
method: 'Hours',
|
195
|
+
multiplier: function() {
|
196
|
+
return 60 * 60 * 1000;
|
197
|
+
}
|
198
|
+
},
|
199
|
+
{
|
200
|
+
unit: 'minute',
|
201
|
+
method: 'Minutes',
|
202
|
+
multiplier: function() {
|
203
|
+
return 60 * 1000;
|
204
|
+
}
|
205
|
+
},
|
206
|
+
{
|
207
|
+
unit: 'second',
|
208
|
+
method: 'Seconds',
|
209
|
+
multiplier: function() {
|
210
|
+
return 1000;
|
211
|
+
}
|
212
|
+
},
|
213
|
+
{
|
214
|
+
unit: 'millisecond',
|
215
|
+
method: 'Milliseconds',
|
216
|
+
multiplier: function() {
|
217
|
+
return 1;
|
218
|
+
}
|
219
|
+
}
|
220
|
+
];
|
221
|
+
|
222
|
+
|
223
|
+
|
224
|
+
|
225
|
+
// Date Localization
|
226
|
+
|
227
|
+
var Localizations = {};
|
228
|
+
|
229
|
+
var CommonLocales = {
|
230
|
+
|
231
|
+
'en': '2;;January,February,March,April,May,June,July,August,September,October,November,December;Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday;millisecond:|s,second:|s,minute:|s,hour:|s,day:|s,week:|s,month:|s,year:|s;one,two,three,four,five,six,seven,eight,nine,ten;a,an,the;the,st|nd|rd|th,of;{num} {unit} {sign},{num} {unit=4-5} {sign} {day},{weekday?} {month} {date}{1} {year?} {time?},{date} {month} {year},{month} {year},{shift?} {weekday} {time?},{shift} week {weekday} {time?},{shift} {unit=5-7},{0} {edge} of {shift?} {unit=4-7?}{month?}{year?},{weekday} {2} {shift} week,{0} {date}{1} of {month},{0}{month?} {date?}{1} of {shift} {unit=6-7},{day} at {time?},{time} {day};{Month} {d}, {yyyy};,yesterday,today,tomorrow;,ago|before,,from now|after|from;,last,the|this,next;last day,end,,first day|beginning',
|
232
|
+
|
233
|
+
'ja': '1;月;;日曜日,月曜日,火曜日,水曜日,木曜日,金曜日,土曜日;ミリ秒,秒,分,時間,日,週間|週,ヶ月|ヵ月|月,年;;;;{num}{unit}{sign},{shift}{unit=5-7}{weekday?},{year}年{month?}月?{date?}日?,{month}月{date?}日?,{date}日;{yyyy}年{M}月{d}日;一昨日,昨日,今日,明日,明後日;,前,,後;,去|先,,来',
|
234
|
+
|
235
|
+
'ko': '1;월;;일요일,월요일,화요일,수요일,목요일,금요일,토요일;밀리초,초,분,시간,일,주,개월|달,년;일|한,이,삼,사,오,육,칠,팔,구,십;;;{num}{unit} {sign},{shift} {unit=5-7},{shift} {unit=5?} {weekday},{year}년{month?}월?{date?}일?,{month}월{date?}일?,{date}일;{yyyy}년{M}월{d}일;그저께,어제,오늘,내일,모레;,전,,후;,지난|작,이번,다음|내',
|
236
|
+
|
237
|
+
'ru': '4;;Январ:я|ь,Феврал:я|ь,Март:а|,Апрел:я|ь,Ма:я|й,Июн:я|ь,Июл:я|ь,Август:а|,Сентябр:я|ь,Октябр:я|ь,Ноябр:я|ь,Декабр:я|ь;Воскресенье,Понедельник,Вторник,Среда,Четверг,Пятница,Суббота;миллисекунд:а|у|ы|,секунд:а|у|ы|,минут:а|у|ы|,час:||а|ов,день|день|дня|дней,недел:я|ю|и|ь|е,месяц:||а|ев|е,год|год|года|лет|году;од:ин|ну,дв:а|е,три,четыре,пять,шесть,семь,восемь,девять,десять;;в|на,года;{num} {unit} {sign},{sign} {num} {unit},{date} {month} {year?} {1},{month} {year},{0} {shift} {unit=5-7};{d} {month} {yyyy} года;позавчера,вчера,сегодня,завтра,послезавтра;,назад,,через;,прошло:й|м,,следующе:й|м',
|
238
|
+
|
239
|
+
'es': '6;;enero,febrero,marzo,abril,mayo,junio,julio,agosto,septiembre,octubre,noviembre,diciembre;domingo,lunes,martes,miércoles|miercoles,jueves,viernes,sábado|sabado;milisegundo:|s,segundo:|s,minuto:|s,hora:|s,día|días|dia|dias,semana:|s,mes:|es,año|años|ano|anos;uno,dos,tres,cuatro,cinco,seis,siete,ocho,nueve,diez;;el,de;{sign} {num} {unit},{num} {unit} {sign},{date?} {1} {month} {1} {year?},{0} {unit=5-7} {shift},{0} {shift} {unit=5-7};{d} de {month} de {yyyy};anteayer,ayer,hoy,mañana|manana;,hace,,de ahora;,pasad:o|a,,próximo|próxima|proximo|proxima',
|
240
|
+
|
241
|
+
'pt': '6;;janeiro,fevereiro,março,abril,maio,junho,julho,agosto,setembro,outubro,novembro,dezembro;domingo,segunda-feira,terça-feira,quarta-feira,quinta-feira,sexta-feira,sábado|sabado;milisegundo:|s,segundo:|s,minuto:|s,hora:|s,dia:|s,semana:|s,mês|mêses|mes|meses,ano:|s;um,dois,três|tres,quatro,cinco,seis,sete,oito,nove,dez,uma,duas;;a,de;{num} {unit} {sign},{sign} {num} {unit},{date?} {1} {month} {1} {year?},{0} {unit=5-7} {shift},{0} {shift} {unit=5-7};{d} de {month} de {yyyy};anteontem,ontem,hoje,amanh:ã|a;,atrás|atras|há|ha,,daqui a;,passad:o|a,,próximo|próxima|proximo|proxima',
|
242
|
+
|
243
|
+
'fr': '2;;janvier,février|fevrier,mars,avril,mai,juin,juillet,août,septembre,octobre,novembre,décembre|decembre;dimanche,lundi,mardi,mercredi,jeudi,vendredi,samedi;milliseconde:|s,seconde:|s,minute:|s,heure:|s,jour:|s,semaine:|s,mois,an:|s|née|nee;un:|e,deux,trois,quatre,cinq,six,sept,huit,neuf,dix;;l\'|la|le;{sign} {num} {unit},{sign} {num} {unit},{0} {date?} {month} {year?},{0} {unit=5-7} {shift};{d} {month} {yyyy};,hier,aujourd\'hui,demain;,il y a,,dans|d\'ici;,derni:er|ère|ere,,prochain:|e',
|
244
|
+
|
245
|
+
'it': '2;;Gennaio,Febbraio,Marzo,Aprile,Maggio,Giugno,Luglio,Agosto,Settembre,Ottobre,Novembre,Dicembre;Domenica,Luned:ì|i,Marted:ì|i,Mercoled:ì|i,Gioved:ì|i,Venerd:ì|i,Sabato;millisecond:o|i,second:o|i,minut:o|i,or:a|e,giorn:o|i,settiman:a|e,mes:e|i,ann:o|i;un:|\'|a|o,due,tre,quattro,cinque,sei,sette,otto,nove,dieci;;l\'|la|il;{num} {unit} {sign},{weekday?} {date?} {month} {year?},{0} {unit=5-7} {shift},{0} {shift} {unit=5-7};{d} {month} {yyyy};,ieri,oggi,domani,dopodomani;,fa,,da adesso;,scors:o|a,,prossim:o|a',
|
246
|
+
|
247
|
+
'de': '2;;Januar,Februar,März|Marz,April,Mai,Juni,Juli,August,September,Oktober,November,Dezember;Sonntag,Montag,Dienstag,Mittwoch,Donnerstag,Freitag,Samstag;Millisekunde:|n,Sekunde:|n,Minute:|n,Stunde:|n,Tag:|en,Woche:|n,Monat:|en,Jahr:|en;ein:|e|er|em|en,zwei,drei,vier,fuenf,sechs,sieben,acht,neun,zehn;;der;{sign} {num} {unit},{num} {unit} {sign},{num} {unit} {sign},{sign} {num} {unit},{weekday?} {date?} {month} {year?},{shift} {unit=5-7};{d}. {Month} {yyyy};vorgestern,gestern,heute,morgen,übermorgen|ubermorgen|uebermorgen;,vor:|her,,in;,letzte:|r|n|s,,nächste:|r|n|s+naechste:|r|n|s',
|
248
|
+
|
249
|
+
'zh-TW': '1;月;;日,一,二,三,四,五,六;毫秒,秒鐘,分鐘,小時,天,個星期|週,個月,年;;;日|號;{num}{unit}{sign},星期{weekday},{shift}{unit=5-7},{shift}{unit=5}{weekday},{year}年{month?}月?{date?}{0},{month}月{date?}{0},{date}{0};{yyyy}年{M}月{d}日;前天,昨天,今天,明天,後天;,前,,後;,上|去,這,下|明',
|
250
|
+
|
251
|
+
'zh-CN': '1;月;;日,一,二,三,四,五,六;毫秒,秒钟,分钟,小时,天,个星期|周,个月,年;;;日|号;{num}{unit}{sign},星期{weekday},{shift}{unit=5-7},{shift}{unit=5}{weekday},{year}年{month?}月?{date?}{0},{month}月{date?}{0},{date}{0};{yyyy}年{M}月{d}日;前天,昨天,今天,明天,后天;,前,,后;,上|去,这,下|明'
|
252
|
+
|
253
|
+
}
|
254
|
+
|
255
|
+
function checkLocaleFormatsAdded(loc) {
|
256
|
+
var code = loc['code'];
|
257
|
+
if(loc.formatsAdded) return;
|
258
|
+
addDateInputFormat('(' + loc['months'].compact().join('|') + ')', ['month'], code);
|
259
|
+
addDateInputFormat('(' + loc['weekdays'].compact().join('|') + ')', ['weekday'], code);
|
260
|
+
addDateInputFormat('(' + loc['modifiers'].filter(function(m){ return m.name === 'day'; }).map('src').join('|') + ')', ['day'], code);
|
261
|
+
loc['formats'].each(function(src) {
|
262
|
+
loc.addFormat(src, code, false);
|
263
|
+
});
|
264
|
+
loc.formatsAdded = true;
|
265
|
+
}
|
266
|
+
|
267
|
+
function addDateInputFormat(format, match, locale, variant, method) {
|
268
|
+
method = method || 'push';
|
269
|
+
DateInputFormats[method]({
|
270
|
+
variant: variant,
|
271
|
+
locale: locale,
|
272
|
+
reg: regexp('^' + format + '$', 'i'),
|
273
|
+
to: match
|
274
|
+
});
|
275
|
+
}
|
276
|
+
|
277
|
+
function getLocalization(code, fallback, set) {
|
278
|
+
if(fallback && (!object.isString(code) || !code)) code = Date['currentLocale'];
|
279
|
+
if(code && !Localizations[code] || set) initializeLocalization(code, set);
|
280
|
+
return Localizations[code];
|
281
|
+
}
|
282
|
+
|
283
|
+
function initializeLocalization(code, set) {
|
284
|
+
set = set || getCommonLocalization(code);
|
285
|
+
if(!set) {
|
286
|
+
throw new Error('Invalid locale.');
|
287
|
+
}
|
288
|
+
|
289
|
+
function eachAlternate(str, fn) {
|
290
|
+
str = str.split('+').map(function(split) {
|
291
|
+
return split.replace(/(.+):(.+)$/, function(full, base, suffixes) {
|
292
|
+
return suffixes.split('|').map(function(suffix) {
|
293
|
+
return base + suffix;
|
294
|
+
}).join('|');
|
295
|
+
});
|
296
|
+
}).join('|');
|
297
|
+
return str.split('|').each(fn);
|
298
|
+
}
|
299
|
+
|
300
|
+
function setArray(name, abbreviate, multiple) {
|
301
|
+
var arr = [];
|
302
|
+
if(!set[name]) return;
|
303
|
+
set[name].forEach(function(el, i) {
|
304
|
+
eachAlternate(el, function(str, j) {
|
305
|
+
arr[j * multiple + i] = str.toLowerCase();
|
306
|
+
});
|
307
|
+
});
|
308
|
+
if(abbreviate) arr = arr.concat(set[name].map(function(str) {
|
309
|
+
return str.slice(0,3).toLowerCase();
|
310
|
+
}));
|
311
|
+
return set[name] = arr;
|
312
|
+
}
|
313
|
+
|
314
|
+
function getDigit(start, stop) {
|
315
|
+
var str = '[0-90-9]' + (start ? '{' + start + ',' + stop + '}' : '+');
|
316
|
+
if(set['digits']) str += '|[' + set['digits'] + ']+';
|
317
|
+
return str;
|
318
|
+
}
|
319
|
+
|
320
|
+
function getNum() {
|
321
|
+
var arr = [getDigit()].concat(set['articles']);
|
322
|
+
if(!set['digits']) arr = arr.concat(set['numbers']);
|
323
|
+
return arr.compact().join('|');
|
324
|
+
}
|
325
|
+
|
326
|
+
function setModifiers() {
|
327
|
+
var arr = [];
|
328
|
+
set.modifiersByName = {};
|
329
|
+
set['modifiers'].each(function(modifier) {
|
330
|
+
eachAlternate(modifier.src, function(t) {
|
331
|
+
set.modifiersByName[t] = modifier;
|
332
|
+
arr.push({ name: modifier.name, src: t, value: modifier.value });
|
333
|
+
});
|
334
|
+
});
|
335
|
+
arr.groupBy('name', function(name, group) {
|
336
|
+
group = group.map('src');
|
337
|
+
if(name === 'day') group = group.concat(set['weekdays']);
|
338
|
+
set[name] = group.join('|');
|
339
|
+
});
|
340
|
+
set['modifiers'] = arr;
|
341
|
+
}
|
342
|
+
|
343
|
+
setArray('months', true, 12);
|
344
|
+
setArray('weekdays', true, 7);
|
345
|
+
setArray('units', false, 8);
|
346
|
+
setArray('numbers', false, 10);
|
347
|
+
|
348
|
+
set['code'] = code;
|
349
|
+
set['date'] = getDigit(1,2);
|
350
|
+
set['year'] = getDigit(4,4);
|
351
|
+
set['num'] = getNum();
|
352
|
+
|
353
|
+
setModifiers();
|
354
|
+
|
355
|
+
if(set['monthSuffix']) {
|
356
|
+
set['month'] = getDigit(1,2);
|
357
|
+
set['months'] = (1).upto(12).map(function(n) { return n + set['monthSuffix']; });
|
358
|
+
}
|
359
|
+
Localizations[code] = new Localization(set);
|
360
|
+
}
|
361
|
+
|
362
|
+
function getCommonLocalization(code) {
|
363
|
+
if(code.slice(0,3) == 'en-') code = 'en';
|
364
|
+
if(!CommonLocales[code]) return null;
|
365
|
+
var set = { 'modifiers': [] }, pre = CommonLocales[code].split(';');
|
366
|
+
function bool(n) {
|
367
|
+
return !!(pre[0] & Math.pow(2,n-1));
|
368
|
+
}
|
369
|
+
['months','weekdays','units','numbers','articles','optionals','formats'].each(function(name, i) {
|
370
|
+
set[name] = pre[i + 2] ? pre[i + 2].split(',') : [];
|
371
|
+
});
|
372
|
+
set['outputFormat'] = pre[9];
|
373
|
+
['day','sign','shift','edge'].each(function(name, i) {
|
374
|
+
if(!pre[i + 10]) return;
|
375
|
+
pre[i + 10].split(',').each(function(t, j) {
|
376
|
+
if(t) set['modifiers'].push({ name: name, src: t, value: j - 2 });
|
377
|
+
});
|
378
|
+
});
|
379
|
+
if(bool(1)) {
|
380
|
+
set['digits'] = LowerAsianDigits + UpperAsianDigits;
|
381
|
+
if(set['numbers'].length > 0) {
|
382
|
+
set['digits'] += set['numbers'].join('');
|
383
|
+
} else {
|
384
|
+
set['numbers'] = LowerAsianDigits.split('');
|
385
|
+
}
|
386
|
+
set['monthSuffix'] = pre[1];
|
387
|
+
}
|
388
|
+
set['capitalizeUnit'] = (code == 'de');
|
389
|
+
set['hasPlural'] = bool(2);
|
390
|
+
set['pastRelativeFormat'] = set['formats'][0];
|
391
|
+
set['futureRelativeFormat'] = set['formats'][bool(3) ? 1 : 0];
|
392
|
+
set['durationFormat'] = set['formats'][0].replace(/\s*\{sign\}\s*/, '');
|
393
|
+
return set;
|
394
|
+
}
|
395
|
+
|
396
|
+
function getVariant(locale) {
|
397
|
+
if(!locale) locale = Date['currentLocale'];
|
398
|
+
return locale != 'en' && locale != 'en-US';
|
399
|
+
}
|
400
|
+
|
401
|
+
function Localization(l) {
|
402
|
+
object.merge(this, l);
|
403
|
+
}
|
404
|
+
|
405
|
+
object.merge(Localization.prototype, {
|
406
|
+
|
407
|
+
getMonth: function(n) {
|
408
|
+
if(object.isNumber(n)) {
|
409
|
+
return n - 1;
|
410
|
+
} else {
|
411
|
+
return this['months'].findIndex(regexp(n, 'i')) % 12;
|
412
|
+
}
|
413
|
+
},
|
414
|
+
|
415
|
+
getWeekday: function(n) {
|
416
|
+
return this['weekdays'].findIndex(regexp(n, 'i')) % 7;
|
417
|
+
},
|
418
|
+
|
419
|
+
getNumber: function(n) {
|
420
|
+
var i;
|
421
|
+
if(object.isNumber(n)) {
|
422
|
+
return n;
|
423
|
+
} else if(n && (i = this['numbers'].indexOf(n)) !== -1) {
|
424
|
+
return (i + 1) % 10;
|
425
|
+
} else {
|
426
|
+
return 1;
|
427
|
+
}
|
428
|
+
},
|
429
|
+
|
430
|
+
getNumericDate: function(n) {
|
431
|
+
var self = this;
|
432
|
+
return n.replace(this['numbers'][9], '').each(function(d) {
|
433
|
+
return self.getNumber(d);
|
434
|
+
}).join('');
|
435
|
+
},
|
436
|
+
|
437
|
+
getEnglishUnit: function(n) {
|
438
|
+
return English['units'][this['units'].indexOf(n) % 8];
|
439
|
+
},
|
440
|
+
|
441
|
+
relative: function(adu) {
|
442
|
+
return this.convertAdjustedToFormat(adu, adu[2] > 0 ? 'futureRelativeFormat' : 'pastRelativeFormat');
|
443
|
+
},
|
444
|
+
|
445
|
+
duration: function(ms) {
|
446
|
+
return this.convertAdjustedToFormat(getAdjustedUnit(ms), 'durationFormat');
|
447
|
+
},
|
448
|
+
|
449
|
+
convertAdjustedToFormat: function(adu, format) {
|
450
|
+
var num = adu[0], u = adu[1], ms = adu[2], sign, unit, last, mult;
|
451
|
+
if(this['code'] == 'ru') {
|
452
|
+
last = num.toString().from(-1);
|
453
|
+
switch(true) {
|
454
|
+
case last == 1: mult = 1; break;
|
455
|
+
case last >= 2 && last <= 4: mult = 2; break;
|
456
|
+
default: mult = 3;
|
457
|
+
}
|
458
|
+
} else {
|
459
|
+
mult = this['hasPlural'] && num > 1 ? 1 : 0;
|
460
|
+
}
|
461
|
+
unit = this['units'][mult * 8 + u] || this['units'][u];
|
462
|
+
if(this['capitalizeUnit']) unit = unit.capitalize();
|
463
|
+
sign = this['modifiers'].find(function(m) { return m.name == 'sign' && m.value == (ms > 0 ? 1 : -1); });
|
464
|
+
return this[format].assign({ 'num': num, 'unit': unit, 'sign': sign.src });
|
465
|
+
},
|
466
|
+
|
467
|
+
addFormat: function(src, code, add) {
|
468
|
+
var to = [], loc = this;
|
469
|
+
if(add !== false) loc.formats.push(src);
|
470
|
+
src = src.replace(/\s+/g, '[-,. ]*');
|
471
|
+
src = src.replace(/\{(.+?)\}/g, function(all, k) {
|
472
|
+
var opt = k.match(/\?$/), slice = k.match(/(\d)(?:-(\d))?/), nc = k.match(/^\d+$/), key = k.replace(/[^a-z]+$/, ''), value, arr;
|
473
|
+
if(key === 'time') {
|
474
|
+
to = to.concat(TimeFormat);
|
475
|
+
return opt ? OptionalTime : RequiredTime;
|
476
|
+
}
|
477
|
+
if(nc) {
|
478
|
+
value = loc['optionals'][nc[0]];
|
479
|
+
} else if(loc[key]) {
|
480
|
+
value = loc[key];
|
481
|
+
} else if(loc[key + 's']) {
|
482
|
+
value = loc[key + 's'];
|
483
|
+
if(slice) {
|
484
|
+
// Can't use filter here as Prototype hijacks the method and doesn't
|
485
|
+
// pass an index, so use a simple loop instead!
|
486
|
+
arr = [];
|
487
|
+
value.forEach(function(m, i) {
|
488
|
+
var mod = i % (loc['units'] ? 8 : value.length);
|
489
|
+
if(mod >= slice[1] && mod <= (slice[2] || slice[1])) {
|
490
|
+
arr.push(m);
|
491
|
+
}
|
492
|
+
});
|
493
|
+
value = arr;
|
494
|
+
}
|
495
|
+
value = value.compact().join('|');
|
496
|
+
}
|
497
|
+
if(nc) {
|
498
|
+
return '(?:' + value + ')?';
|
499
|
+
} else {
|
500
|
+
to.push(key);
|
501
|
+
return '(' + value + ')' + (opt ? '?' : '');
|
502
|
+
}
|
503
|
+
});
|
504
|
+
addDateInputFormat(src, to, code);
|
505
|
+
}
|
506
|
+
|
507
|
+
});
|
508
|
+
|
509
|
+
function collectDateArguments(args) {
|
510
|
+
var obj, arr;
|
511
|
+
if(object.isObject(args[0])) {
|
512
|
+
return args;
|
513
|
+
} else if (args.length == 1 && object.isNumber(args[0])) {
|
514
|
+
return [args[0]];
|
515
|
+
}
|
516
|
+
obj = {};
|
517
|
+
DateArgumentUnits.each(function(u,i) {
|
518
|
+
obj[u.unit] = args[i];
|
519
|
+
});
|
520
|
+
return [obj];
|
521
|
+
}
|
522
|
+
|
523
|
+
function convertAsianDigits(str, key) {
|
524
|
+
if(key != 'date' && key != 'month' && key != 'year') return str;
|
525
|
+
return str.replace(AsianDigitReg, function(d) {
|
526
|
+
var index = LowerAsianDigits.indexOf(d);
|
527
|
+
return (index + 1) || '';
|
528
|
+
});
|
529
|
+
}
|
530
|
+
|
531
|
+
function getFormatMatch(match, arr) {
|
532
|
+
var obj = {}, value, num;
|
533
|
+
arr.each(function(key, i) {
|
534
|
+
value = match[i + 1];
|
535
|
+
if(isUndefined(value) || value === '') return;
|
536
|
+
value = convertAsianDigits(value.hankaku('n'), key);
|
537
|
+
if(key === 'year') obj.yearAsString = value;
|
538
|
+
num = parseFloat(value.replace(/,/, '.'));
|
539
|
+
obj[key] = !isNaN(num) ? num : value.toLowerCase();
|
540
|
+
});
|
541
|
+
return obj;
|
542
|
+
}
|
543
|
+
|
544
|
+
function getExtendedDate(f, locale) {
|
545
|
+
var d = new date(), relative = false, loc, variant, format, set, unit, num, tmp;
|
546
|
+
if(object.isDate(f)) {
|
547
|
+
d = f;
|
548
|
+
} else if(object.isNumber(f)) {
|
549
|
+
d = new date(f);
|
550
|
+
} else if(object.isObject(f)) {
|
551
|
+
d = new date().set(f, true);
|
552
|
+
set = f;
|
553
|
+
} else if(object.isString(f)) {
|
554
|
+
// Pre-initialize the localization formats.
|
555
|
+
|
556
|
+
checkLocaleFormatsAdded(getLocalization(locale, true));
|
557
|
+
variant = getVariant(locale);
|
558
|
+
f = f.trim().replace(/\.+$/,'').replace(/^now$/, '');
|
559
|
+
DateInputFormats.each(function(dif) {
|
560
|
+
var match = f.match(dif.reg);
|
561
|
+
if(match) {
|
562
|
+
format = dif;
|
563
|
+
set = getFormatMatch(match, format.to);
|
564
|
+
loc = getLocalization(format.locale, true);
|
565
|
+
|
566
|
+
if(set.timestamp) {
|
567
|
+
d.setTime(0);
|
568
|
+
set = { 'milliseconds': set.timestamp };
|
569
|
+
return false;
|
570
|
+
}
|
571
|
+
|
572
|
+
// If there's a European variant, swap the month and day.
|
573
|
+
if(format.variant && !object.isString(set['month']) && (object.isString(set['date']) || variant)) {
|
574
|
+
tmp = set['month'];
|
575
|
+
set['month'] = set['date'];
|
576
|
+
set['date'] = tmp;
|
577
|
+
}
|
578
|
+
|
579
|
+
// If the year is 2 digits then get the implied century.
|
580
|
+
if(set['year'] && set.yearAsString.length === 2) {
|
581
|
+
set['year'] = getYearFromAbbreviation(set['year']);
|
582
|
+
}
|
583
|
+
|
584
|
+
// Set the month which may be localized.
|
585
|
+
if(set['month']) {
|
586
|
+
set['month'] = loc.getMonth(set['month']);
|
587
|
+
if(set['shift'] && !set['unit']) set['unit'] = 'year';
|
588
|
+
}
|
589
|
+
|
590
|
+
// If there is both a weekday and a date, the date takes precedence.
|
591
|
+
if(set['weekday'] && set['date']) {
|
592
|
+
delete set['weekday'];
|
593
|
+
// Otherwise set a localized weekday.
|
594
|
+
} else if(set['weekday']) {
|
595
|
+
set['weekday'] = loc.getWeekday(set['weekday']);
|
596
|
+
if(set['shift'] && !set['unit']) set['unit'] = 'week';
|
597
|
+
}
|
598
|
+
|
599
|
+
// Relative day localizations such as "today" and "tomorrow".
|
600
|
+
if(set['day'] && (tmp = loc.modifiersByName[set['day']])) {
|
601
|
+
set['day'] = tmp.value;
|
602
|
+
d.resetTime();
|
603
|
+
relative = true;
|
604
|
+
// If the day is a weekday, then set that instead.
|
605
|
+
} else if(set['day'] && (tmp = loc.getWeekday(set['day'])) > -1) {
|
606
|
+
delete set['day'];
|
607
|
+
set['weekday'] = tmp;
|
608
|
+
}
|
609
|
+
|
610
|
+
if(set['date'] && !object.isNumber(set['date'])) {
|
611
|
+
set['date'] = loc.getNumericDate(set['date']);
|
612
|
+
}
|
613
|
+
|
614
|
+
// If the time is 1pm-11pm advance the time by 12 hours.
|
615
|
+
if(set['meridian']) {
|
616
|
+
if(set['meridian'] === 'pm' && set['hour'] < 12) set['hour'] += 12;
|
617
|
+
}
|
618
|
+
|
619
|
+
// Adjust for timezone offset
|
620
|
+
if('offset_hours' in set || 'offset_minutes' in set) {
|
621
|
+
set['utc'] = true;
|
622
|
+
set['offset_minutes'] = set['offset_minutes'] || 0;
|
623
|
+
set['offset_minutes'] += set['offset_hours'] * 60;
|
624
|
+
if(set['offset_sign'] === '-') {
|
625
|
+
set['offset_minutes'] *= -1;
|
626
|
+
}
|
627
|
+
set['minute'] -= set['offset_minutes'];
|
628
|
+
}
|
629
|
+
|
630
|
+
// Date has a unit like "days", "months", etc. are all relative to the current date.
|
631
|
+
if(set['unit']) {
|
632
|
+
relative = true;
|
633
|
+
num = loc.getNumber(set['num']);
|
634
|
+
unit = loc.getEnglishUnit(set['unit']);
|
635
|
+
|
636
|
+
// Shift and unit, ie "next month", "last week", etc.
|
637
|
+
if(set['shift'] || set['edge']) {
|
638
|
+
num *= (tmp = loc.modifiersByName[set['shift']]) ? tmp.value : 0;
|
639
|
+
|
640
|
+
// Relative month and static date: "the 15th of last month"
|
641
|
+
if(unit === 'month' && isDefined(set['date'])) {
|
642
|
+
d.set({ 'day': set['date'] }, true);
|
643
|
+
delete set['date'];
|
644
|
+
}
|
645
|
+
|
646
|
+
// Relative year and static month/date: "June 15th of last year"
|
647
|
+
if(unit === 'year' && isDefined(set['month'])) {
|
648
|
+
d.set({ 'month': set['month'], 'day': set['date'] }, true);
|
649
|
+
delete set['month'];
|
650
|
+
delete set['date'];
|
651
|
+
}
|
652
|
+
}
|
653
|
+
|
654
|
+
// Unit and sign, ie "months ago", "weeks from now", etc.
|
655
|
+
if(set['sign'] && (tmp = loc.modifiersByName[set['sign']])) {
|
656
|
+
num *= tmp.value;
|
657
|
+
}
|
658
|
+
|
659
|
+
// Units can be with non-relative dates, set here. ie "the day after monday"
|
660
|
+
if(isDefined(set['weekday'])) {
|
661
|
+
d.set({'weekday': set['weekday'] }, true);
|
662
|
+
delete set['weekday'];
|
663
|
+
}
|
664
|
+
|
665
|
+
// Finally shift the unit.
|
666
|
+
set[unit] = (set[unit] || 0) + num;
|
667
|
+
}
|
668
|
+
|
669
|
+
if(set['year_sign'] === '-') {
|
670
|
+
set['year'] *= -1;
|
671
|
+
}
|
672
|
+
|
673
|
+
DateUnitsReversed.slice(1,4).each(function(u, i) {
|
674
|
+
var value = set[u.unit], fraction = value % 1;
|
675
|
+
if(fraction) {
|
676
|
+
set[DateUnitsReversed[i].unit] = (fraction * (u.unit === 'second' ? 1000 : 60)).round();
|
677
|
+
set[u.unit] = value | 0;
|
678
|
+
}
|
679
|
+
});
|
680
|
+
return false;
|
681
|
+
}
|
682
|
+
});
|
683
|
+
if(!format) {
|
684
|
+
// The Date constructor does something tricky like checking the number
|
685
|
+
// of arguments so simply passing in undefined won't work.
|
686
|
+
d = f ? new date(f) : new date();
|
687
|
+
} else if(relative) {
|
688
|
+
d.advance(set);
|
689
|
+
} else if(set['utc']) {
|
690
|
+
// UTC times can traverse into other days or even months,
|
691
|
+
// so preemtively reset the time here to prevent this.
|
692
|
+
d.resetTime();
|
693
|
+
d.setUTC(set, true);
|
694
|
+
} else {
|
695
|
+
d.set(set, true);
|
696
|
+
}
|
697
|
+
|
698
|
+
// If there is an "edge" it needs to be set after the
|
699
|
+
// other fields are set. ie "the end of February"
|
700
|
+
if(set && set['edge']) {
|
701
|
+
tmp = loc.modifiersByName[set['edge']];
|
702
|
+
DateUnitsReversed.slice(4).each(function(u) {
|
703
|
+
if(isDefined(set[u.unit])) {
|
704
|
+
unit = u.unit;
|
705
|
+
return false;
|
706
|
+
}
|
707
|
+
});
|
708
|
+
if(unit === 'year') set.specificity = 'month';
|
709
|
+
else if(unit === 'month' || unit === 'week') set.specificity = 'day';
|
710
|
+
d[(tmp.value < 0 ? 'endOf' : 'beginningOf') + unit.capitalize()]();
|
711
|
+
// This value of -2 is arbitrary but it's a nice clean way to hook into this system.
|
712
|
+
if(tmp.value === -2) d.resetTime();
|
713
|
+
}
|
714
|
+
}
|
715
|
+
return {
|
716
|
+
date: d,
|
717
|
+
set: set
|
718
|
+
}
|
719
|
+
}
|
720
|
+
|
721
|
+
function formatDate(date, f, relative, locale) {
|
722
|
+
var adu, loc = getLocalization(locale, true), caps = regexp(/^[A-Z]/), value, l;
|
723
|
+
if(!date.isValid()) {
|
724
|
+
return 'Invalid Date';
|
725
|
+
} else if(Date[f]) {
|
726
|
+
f = Date[f];
|
727
|
+
} else if(object.isFunction(f)) {
|
728
|
+
adu = getAdjustedUnit(date.millisecondsFromNow());
|
729
|
+
f = f.apply(date, adu.concat(loc));
|
730
|
+
}
|
731
|
+
if(!f && !relative) {
|
732
|
+
f = loc['outputFormat'];
|
733
|
+
} else if(!f && relative) {
|
734
|
+
adu = adu || getAdjustedUnit(date.millisecondsFromNow());
|
735
|
+
// Adjust up if time is in ms, as this doesn't
|
736
|
+
// look very good for a standard relative date.
|
737
|
+
if(adu[1] === 0) {
|
738
|
+
adu[1] = 1;
|
739
|
+
adu[0] = 1;
|
740
|
+
}
|
741
|
+
return loc.relative(adu);
|
742
|
+
}
|
743
|
+
DateOutputFormats.each(function(dof) {
|
744
|
+
f = f.replace(regexp('\\{('+dof.token+')(\\d)?\\}', dof.word ? 'i' : ''), function(m,t,d) {
|
745
|
+
var val = dof.format(date, loc, d || 1, t), l = t.length, one = t.match(/^(.)\1+$/);
|
746
|
+
if(dof.word) {
|
747
|
+
if(l === 3) val = val.to(3);
|
748
|
+
if(one || t.match(caps)) val = val.capitalize();
|
749
|
+
} else if(one && !dof.text) {
|
750
|
+
val = (object.isNumber(val) ? val.pad(l) : val.toString()).last(l);
|
751
|
+
}
|
752
|
+
return val;
|
753
|
+
});
|
754
|
+
});
|
755
|
+
return f;
|
756
|
+
}
|
757
|
+
|
758
|
+
function compareDate(d, find, buffer) {
|
759
|
+
var p = getExtendedDate(find), accuracy = 0, loBuffer = 0, hiBuffer = 0, override;
|
760
|
+
if(buffer > 0) {
|
761
|
+
loBuffer = hiBuffer = buffer;
|
762
|
+
override = true;
|
763
|
+
}
|
764
|
+
if(!p.date.isValid()) return false;
|
765
|
+
if(p.set && p.set.specificity) {
|
766
|
+
DateUnits.each(function(u, i) {
|
767
|
+
if(u.unit === p.set.specificity) {
|
768
|
+
accuracy = u.multiplier(p.date, d - p.date) - 1;
|
769
|
+
}
|
770
|
+
});
|
771
|
+
if(p.set['edge'] || p.set['shift']) {
|
772
|
+
p.date['beginningOf' + p.set.specificity.capitalize()]();
|
773
|
+
}
|
774
|
+
if(!override && p.set['sign'] && p.set.specificity != 'millisecond') {
|
775
|
+
// If the time is relative, there can occasionally be an disparity between the relative date
|
776
|
+
// and "now", which it is being compared to, so set an extra buffer to account for this.
|
777
|
+
loBuffer = 50;
|
778
|
+
hiBuffer = -50;
|
779
|
+
}
|
780
|
+
}
|
781
|
+
var t = d.getTime();
|
782
|
+
var min = p.date.getTime();
|
783
|
+
var max = min + accuracy;
|
784
|
+
if(p.set && p.set.specificity == 'week' && new Date(max + 1).getHours() != 0) {
|
785
|
+
max += date['DSTOffset'];
|
786
|
+
}
|
787
|
+
return t >= (min - loBuffer) && t <= (max + hiBuffer);
|
788
|
+
}
|
789
|
+
|
790
|
+
function updateDate(date, params, reset, utc, advance) {
|
791
|
+
if(object.isNumber(params) && advance) {
|
792
|
+
// If param is a number and we're advancing, the number is presumed to be milliseconds.
|
793
|
+
params = { 'milliseconds': params };
|
794
|
+
} else if(object.isNumber(params)) {
|
795
|
+
// Otherwise just set the timestamp and return.
|
796
|
+
date.setTime(params);
|
797
|
+
return date;
|
798
|
+
}
|
799
|
+
|
800
|
+
// "date" can also be passed for the day
|
801
|
+
if(params['date']) params['day'] = params['date'];
|
802
|
+
// If a weekday is included in the params, set it ahead of time and set the params
|
803
|
+
// to reflect the updated date so that resetting works properly.
|
804
|
+
if(!advance && isUndefined(params['day']) && isDefined(params['weekday'])) {
|
805
|
+
callDateMethod(date, 'set', utc, 'Weekday', params['weekday'])
|
806
|
+
params['day'] = callDateMethod(date, 'get', utc, 'Date');
|
807
|
+
delete params['weekday'];
|
808
|
+
}
|
809
|
+
// Reset any unit lower than the least specific unit set. Do not do this for weeks
|
810
|
+
// or for years. This needs to be performed before the acutal setting of the date
|
811
|
+
// because the order needs to be reversed in order to get the lowest specificity.
|
812
|
+
// The order of the date setting is also fixed because higher order units can be
|
813
|
+
// overwritten by lower order units, such as setting hour: 3, minute: 345, etc.
|
814
|
+
DateUnitsReversed.each(function(u) {
|
815
|
+
if(isDefined(params[u.unit]) || isDefined(params[u.unit + 's'])) {
|
816
|
+
params.specificity = u.unit;
|
817
|
+
return false;
|
818
|
+
} else if(reset && u.unit !== 'week' && u.unit !== 'year') {
|
819
|
+
callDateMethod(date, 'set', utc, u.method, (u.unit === 'day') ? 1 : 0);
|
820
|
+
}
|
821
|
+
});
|
822
|
+
// Now actually set or advance the date in order, higher units first.
|
823
|
+
DateUnits.each(function(u,i) {
|
824
|
+
var unit = u.unit;
|
825
|
+
var method = u.method;
|
826
|
+
var value = isDefined(params[unit]) ? params[unit] : params[unit + 's'];
|
827
|
+
if(isUndefined(value)) return;
|
828
|
+
if(advance) {
|
829
|
+
if(unit === 'week') {
|
830
|
+
value = (params['day'] || 0) + (value * 7);
|
831
|
+
method = 'Date';
|
832
|
+
}
|
833
|
+
value = (value * advance) + callDateMethod(date, 'get', '', method);
|
834
|
+
}
|
835
|
+
callDateMethod(date, 'set', utc, method, value);
|
836
|
+
if(unit === 'month') {
|
837
|
+
checkMonthTraversal(date, value);
|
838
|
+
}
|
839
|
+
});
|
840
|
+
return date;
|
841
|
+
}
|
842
|
+
|
843
|
+
function callDateMethod(d, prefix, utc, method, value) {
|
844
|
+
return d[prefix + (utc ? 'UTC' : '') + method](value);
|
845
|
+
}
|
846
|
+
|
847
|
+
// If the year is two digits, add the most appropriate century prefix.
|
848
|
+
function getYearFromAbbreviation(year) {
|
849
|
+
return (new date().getFullYear() / 100).round() * 100 - (year / 100).round() * 100 + year;
|
850
|
+
}
|
851
|
+
|
852
|
+
function getShortHour(d, utc) {
|
853
|
+
var hours = callDateMethod(d, 'get', utc, 'Hours');
|
854
|
+
return hours === 0 ? 12 : hours - ((hours / 13 | 0) * 12);
|
855
|
+
}
|
856
|
+
|
857
|
+
function getMeridian(d, utc) {
|
858
|
+
var hours = callDateMethod(d, 'get', utc, 'Hours');
|
859
|
+
return hours < 12 ? 'am' : 'pm';
|
860
|
+
}
|
861
|
+
|
862
|
+
// weeksSince won't work here as the result needs to be floored, not rounded.
|
863
|
+
function getWeekNumber(date) {
|
864
|
+
var dow = date.getDay() || 7;
|
865
|
+
date.addDays(4 - dow).resetTime();
|
866
|
+
return 1 + (date.daysSince(date.clone().beginningOfYear()) / 7 | 0);
|
867
|
+
}
|
868
|
+
|
869
|
+
function getAdjustedUnit(ms) {
|
870
|
+
var next, ams = ms.abs(), value = ams, unit = 0;
|
871
|
+
DateUnitsReversed.from(1).each(function(u, i) {
|
872
|
+
next = (ams / u.multiplier() * 10).round() / 10 | 0;
|
873
|
+
if(next >= 1) {
|
874
|
+
value = next;
|
875
|
+
unit = i + 1;
|
876
|
+
}
|
877
|
+
});
|
878
|
+
return [value, unit, ms];
|
879
|
+
}
|
880
|
+
|
881
|
+
|
882
|
+
// If the month is being set, then we don't want to accidentally
|
883
|
+
// traverse into a new month just because the target month doesn't have enough
|
884
|
+
// days. In other words, "5 months ago" from July 30th is still February, even
|
885
|
+
// though there is no February 30th, so it will of necessity be February 28th
|
886
|
+
// (or 29th in the case of a leap year).
|
887
|
+
|
888
|
+
function checkMonthTraversal(date, targetMonth) {
|
889
|
+
if(targetMonth < 0) targetMonth += 12;
|
890
|
+
if(targetMonth % 12 != date.getMonth()) {
|
891
|
+
date.setDate(0);
|
892
|
+
}
|
893
|
+
}
|
894
|
+
|
895
|
+
function createDate(args) {
|
896
|
+
var f;
|
897
|
+
if(object.isNumber(args[1])) {
|
898
|
+
// If the second argument is a number, then we have an enumerated constructor type as in "new Date(2003, 2, 12);"
|
899
|
+
f = collectDateArguments(args)[0];
|
900
|
+
} else {
|
901
|
+
f = args[0];
|
902
|
+
}
|
903
|
+
return getExtendedDate(f, args[1]).date;
|
904
|
+
}
|
905
|
+
|
906
|
+
|
907
|
+
|
908
|
+
/***
|
909
|
+
* @method [units]Since([d], [locale] = currentLocale)
|
910
|
+
* @returns Number
|
911
|
+
* @short Returns the time since [d] in the appropriate unit.
|
912
|
+
* @extra [d] will accept a date object, timestamp, or text format. If not specified, [d] is assumed to be now. [locale] can be passed to specify the locale that the date is in. For more see @date_format.
|
913
|
+
* @example
|
914
|
+
*
|
915
|
+
* Date.create().millisecondsSince('1 hour ago') -> 3,600,000
|
916
|
+
* Date.create().daysSince('1 week ago') -> 7
|
917
|
+
* Date.create().yearsSince('15 years ago') -> 15
|
918
|
+
* Date.create('15 years ago').yearsAgo() -> 15
|
919
|
+
*
|
920
|
+
***
|
921
|
+
* @method millisecondsSince()
|
922
|
+
* @set unitsSince
|
923
|
+
***
|
924
|
+
* @method secondsSince()
|
925
|
+
* @set unitsSince
|
926
|
+
***
|
927
|
+
* @method minutesSince()
|
928
|
+
* @set unitsSince
|
929
|
+
***
|
930
|
+
* @method hoursSince()
|
931
|
+
* @set unitsSince
|
932
|
+
***
|
933
|
+
* @method daysSince()
|
934
|
+
* @set unitsSince
|
935
|
+
***
|
936
|
+
* @method weeksSince()
|
937
|
+
* @set unitsSince
|
938
|
+
***
|
939
|
+
* @method monthsSince()
|
940
|
+
* @set unitsSince
|
941
|
+
***
|
942
|
+
* @method yearsSince()
|
943
|
+
* @set unitsSince
|
944
|
+
***
|
945
|
+
* @method [units]Ago()
|
946
|
+
* @returns Number
|
947
|
+
* @short Returns the time ago in the appropriate unit.
|
948
|
+
* @example
|
949
|
+
*
|
950
|
+
* Date.create('last year').millisecondsAgo() -> 3,600,000
|
951
|
+
* Date.create('last year').daysAgo() -> 7
|
952
|
+
* Date.create('last year').yearsAgo() -> 15
|
953
|
+
*
|
954
|
+
***
|
955
|
+
* @method millisecondsAgo()
|
956
|
+
* @set unitsAgo
|
957
|
+
***
|
958
|
+
* @method secondsAgo()
|
959
|
+
* @set unitsAgo
|
960
|
+
***
|
961
|
+
* @method minutesAgo()
|
962
|
+
* @set unitsAgo
|
963
|
+
***
|
964
|
+
* @method hoursAgo()
|
965
|
+
* @set unitsAgo
|
966
|
+
***
|
967
|
+
* @method daysAgo()
|
968
|
+
* @set unitsAgo
|
969
|
+
***
|
970
|
+
* @method weeksAgo()
|
971
|
+
* @set unitsAgo
|
972
|
+
***
|
973
|
+
* @method monthsAgo()
|
974
|
+
* @set unitsAgo
|
975
|
+
***
|
976
|
+
* @method yearsAgo()
|
977
|
+
* @set unitsAgo
|
978
|
+
***
|
979
|
+
* @method [units]Until([d], [locale] = currentLocale)
|
980
|
+
* @returns Number
|
981
|
+
* @short Returns the time until [d] in the appropriate unit.
|
982
|
+
* @extra [d] will accept a date object, timestamp, or text format. If not specified, [d] is assumed to be now. [locale] can be passed to specify the locale that the date is in. %[unit]FromNow% is provided as an alias to make this more readable. For more see @date_format.
|
983
|
+
* @example
|
984
|
+
*
|
985
|
+
* Date.create().millisecondsUntil('1 hour from now') -> 3,600,000
|
986
|
+
* Date.create().daysUntil('1 week from now') -> 7
|
987
|
+
* Date.create().yearsUntil('15 years from now') -> 15
|
988
|
+
* Date.create('15 years from now').yearsFromNow() -> 15
|
989
|
+
*
|
990
|
+
***
|
991
|
+
* @method millisecondsUntil()
|
992
|
+
* @set unitsUntil
|
993
|
+
***
|
994
|
+
* @method secondsUntil()
|
995
|
+
* @set unitsUntil
|
996
|
+
***
|
997
|
+
* @method minutesUntil()
|
998
|
+
* @set unitsUntil
|
999
|
+
***
|
1000
|
+
* @method hoursUntil()
|
1001
|
+
* @set unitsUntil
|
1002
|
+
***
|
1003
|
+
* @method daysUntil()
|
1004
|
+
* @set unitsUntil
|
1005
|
+
***
|
1006
|
+
* @method weeksUntil()
|
1007
|
+
* @set unitsUntil
|
1008
|
+
***
|
1009
|
+
* @method monthsUntil()
|
1010
|
+
* @set unitsUntil
|
1011
|
+
***
|
1012
|
+
* @method yearsUntil()
|
1013
|
+
* @set unitsUntil
|
1014
|
+
***
|
1015
|
+
* @method [units]FromNow()
|
1016
|
+
* @returns Number
|
1017
|
+
* @short Returns the time from now in the appropriate unit.
|
1018
|
+
* @example
|
1019
|
+
*
|
1020
|
+
* Date.create('next year').millisecondsFromNow() -> 3,600,000
|
1021
|
+
* Date.create('next year').daysFromNow() -> 7
|
1022
|
+
* Date.create('next year').yearsFromNow() -> 15
|
1023
|
+
*
|
1024
|
+
***
|
1025
|
+
* @method millisecondsFromNow()
|
1026
|
+
* @set unitsFromNow
|
1027
|
+
***
|
1028
|
+
* @method secondsFromNow()
|
1029
|
+
* @set unitsFromNow
|
1030
|
+
***
|
1031
|
+
* @method minutesFromNow()
|
1032
|
+
* @set unitsFromNow
|
1033
|
+
***
|
1034
|
+
* @method hoursFromNow()
|
1035
|
+
* @set unitsFromNow
|
1036
|
+
***
|
1037
|
+
* @method daysFromNow()
|
1038
|
+
* @set unitsFromNow
|
1039
|
+
***
|
1040
|
+
* @method weeksFromNow()
|
1041
|
+
* @set unitsFromNow
|
1042
|
+
***
|
1043
|
+
* @method monthsFromNow()
|
1044
|
+
* @set unitsFromNow
|
1045
|
+
***
|
1046
|
+
* @method yearsFromNow()
|
1047
|
+
* @set unitsFromNow
|
1048
|
+
***
|
1049
|
+
* @method add[Units](<num>)
|
1050
|
+
* @returns Date
|
1051
|
+
* @short Adds <num> of the unit to the date.
|
1052
|
+
* @extra Note that "months" is ambiguous as a unit of time. If the target date falls on a day that does not exist (ie. August 31 -> February 31), the date will be shifted to the last day of the month. Don't use this method if you need precision.
|
1053
|
+
* @example
|
1054
|
+
*
|
1055
|
+
* Date.create().addMilliseconds(5) -> current time + 5 milliseconds
|
1056
|
+
* Date.create().addDays(5) -> current time + 5 days
|
1057
|
+
* Date.create().addYears(5) -> current time + 5 years
|
1058
|
+
*
|
1059
|
+
***
|
1060
|
+
* @method addMilliseconds()
|
1061
|
+
* @set addUnits
|
1062
|
+
***
|
1063
|
+
* @method addSeconds()
|
1064
|
+
* @set addUnits
|
1065
|
+
***
|
1066
|
+
* @method addMinutes()
|
1067
|
+
* @set addUnits
|
1068
|
+
***
|
1069
|
+
* @method addHours()
|
1070
|
+
* @set addUnits
|
1071
|
+
***
|
1072
|
+
* @method addDays()
|
1073
|
+
* @set addUnits
|
1074
|
+
***
|
1075
|
+
* @method addWeeks()
|
1076
|
+
* @set addUnits
|
1077
|
+
***
|
1078
|
+
* @method addMonths()
|
1079
|
+
* @set addUnits
|
1080
|
+
***
|
1081
|
+
* @method addYears()
|
1082
|
+
* @set addUnits
|
1083
|
+
***
|
1084
|
+
* @method isLast[Unit]()
|
1085
|
+
* @returns Boolean
|
1086
|
+
* @short Returns true if the date is last week/month/year.
|
1087
|
+
* @example
|
1088
|
+
*
|
1089
|
+
* Date.create('yesterday').isLastWeek() -> true or false?
|
1090
|
+
* Date.create('yesterday').isLastMonth() -> probably not...
|
1091
|
+
* Date.create('yesterday').isLastYear() -> even less likely...
|
1092
|
+
*
|
1093
|
+
***
|
1094
|
+
* @method isThis[Unit]()
|
1095
|
+
* @returns Boolean
|
1096
|
+
* @short Returns true if the date is this week/month/year.
|
1097
|
+
* @example
|
1098
|
+
*
|
1099
|
+
* Date.create('tomorrow').isThisWeek() -> true or false?
|
1100
|
+
* Date.create('tomorrow').isThisMonth() -> probably...
|
1101
|
+
* Date.create('tomorrow').isThisYear() -> signs point to yes...
|
1102
|
+
*
|
1103
|
+
***
|
1104
|
+
* @method isNext[Unit]()
|
1105
|
+
* @returns Boolean
|
1106
|
+
* @short Returns true if the date is next week/month/year.
|
1107
|
+
* @example
|
1108
|
+
*
|
1109
|
+
* Date.create('tomorrow').isNextWeek() -> true or false?
|
1110
|
+
* Date.create('tomorrow').isNextMonth() -> probably not...
|
1111
|
+
* Date.create('tomorrow').isNextYear() -> even less likely...
|
1112
|
+
*
|
1113
|
+
***
|
1114
|
+
* @method isLastWeek()
|
1115
|
+
* @set isLastUnit
|
1116
|
+
***
|
1117
|
+
* @method isLastMonth()
|
1118
|
+
* @set isLastUnit
|
1119
|
+
***
|
1120
|
+
* @method isLastYear()
|
1121
|
+
* @set isLastUnit
|
1122
|
+
***
|
1123
|
+
* @method isThisWeek()
|
1124
|
+
* @set isThisUnit
|
1125
|
+
***
|
1126
|
+
* @method isThisMonth()
|
1127
|
+
* @set isThisUnit
|
1128
|
+
***
|
1129
|
+
* @method isThisYear()
|
1130
|
+
* @set isThisUnit
|
1131
|
+
***
|
1132
|
+
* @method isNextWeek()
|
1133
|
+
* @set isNextUnit
|
1134
|
+
***
|
1135
|
+
* @method isNextMonth()
|
1136
|
+
* @set isNextUnit
|
1137
|
+
***
|
1138
|
+
* @method isNextYear()
|
1139
|
+
* @set isNextUnit
|
1140
|
+
***
|
1141
|
+
* @method beginningOf[Unit]()
|
1142
|
+
* @returns Date
|
1143
|
+
* @short Sets the date to the beginning of the appropriate unit.
|
1144
|
+
* @example
|
1145
|
+
*
|
1146
|
+
* Date.create().beginningOfDay() -> the beginning of today (resets the time)
|
1147
|
+
* Date.create().beginningOfWeek() -> the beginning of the week
|
1148
|
+
* Date.create().beginningOfMonth() -> the beginning of the month
|
1149
|
+
* Date.create().beginningOfYear() -> the beginning of the year
|
1150
|
+
*
|
1151
|
+
***
|
1152
|
+
* @method endOf[Unit]()
|
1153
|
+
* @returns Date
|
1154
|
+
* @short Sets the date to the end of the appropriate unit.
|
1155
|
+
* @example
|
1156
|
+
*
|
1157
|
+
* Date.create().endOfDay() -> the end of today (sets the time to 23:59:59.999)
|
1158
|
+
* Date.create().endOfWeek() -> the end of the week
|
1159
|
+
* Date.create().endOfMonth() -> the end of the month
|
1160
|
+
* Date.create().endOfYear() -> the end of the year
|
1161
|
+
*
|
1162
|
+
***
|
1163
|
+
* @method beginningOfDay()
|
1164
|
+
* @set beginningOfUnit
|
1165
|
+
***
|
1166
|
+
* @method beginningOfWeek()
|
1167
|
+
* @set beginningOfUnit
|
1168
|
+
***
|
1169
|
+
* @method beginningOfMonth()
|
1170
|
+
* @set beginningOfUnit
|
1171
|
+
***
|
1172
|
+
* @method beginningOfYear()
|
1173
|
+
* @set beginningOfUnit
|
1174
|
+
***
|
1175
|
+
* @method endOfDay()
|
1176
|
+
* @set endOfUnit
|
1177
|
+
***
|
1178
|
+
* @method endOfWeek()
|
1179
|
+
* @set endOfUnit
|
1180
|
+
***
|
1181
|
+
* @method endOfMonth()
|
1182
|
+
* @set endOfUnit
|
1183
|
+
***
|
1184
|
+
* @method endOfYear()
|
1185
|
+
* @set endOfUnit
|
1186
|
+
***/
|
1187
|
+
function buildDateMethods() {
|
1188
|
+
var methods = {};
|
1189
|
+
DateUnits.each(function(u, i) {
|
1190
|
+
var unit = u.unit;
|
1191
|
+
var caps = unit.capitalize();
|
1192
|
+
var multiplier = u.multiplier();
|
1193
|
+
var since = function(f, code) {
|
1194
|
+
return ((this.getTime() - date.create(f, code).getTime()) / multiplier).round();
|
1195
|
+
};
|
1196
|
+
var until = function(f, code) {
|
1197
|
+
return ((date.create(f, code).getTime() - this.getTime()) / multiplier).round();
|
1198
|
+
};
|
1199
|
+
methods[unit+'sAgo'] = until;
|
1200
|
+
methods[unit+'sUntil'] = until;
|
1201
|
+
methods[unit+'sSince'] = since;
|
1202
|
+
methods[unit+'sFromNow'] = since;
|
1203
|
+
methods['add'+caps+'s'] = function(num) {
|
1204
|
+
var set = {};
|
1205
|
+
set[unit] = num;
|
1206
|
+
return this.advance(set);
|
1207
|
+
};
|
1208
|
+
buildNumberToDateAlias(unit, multiplier);
|
1209
|
+
if(i < 3) {
|
1210
|
+
['Last','This','Next'].each(function(shift) {
|
1211
|
+
methods['is' + shift + caps] = function() {
|
1212
|
+
return this.is(shift + ' ' + unit);
|
1213
|
+
};
|
1214
|
+
});
|
1215
|
+
}
|
1216
|
+
if(i < 4) {
|
1217
|
+
methods['beginningOf' + caps] = function() {
|
1218
|
+
var set = {};
|
1219
|
+
switch(unit) {
|
1220
|
+
case 'year': set['year'] = this.getFullYear(); break;
|
1221
|
+
case 'month': set['month'] = this.getMonth(); break;
|
1222
|
+
case 'day': set['day'] = this.getDate(); break;
|
1223
|
+
case 'week': set['weekday'] = 0; break;
|
1224
|
+
}
|
1225
|
+
return this.set(set, true);
|
1226
|
+
};
|
1227
|
+
methods['endOf' + caps] = function() {
|
1228
|
+
var set = { 'hours': 23, 'minutes': 59, 'seconds': 59, 'milliseconds': 999 };
|
1229
|
+
switch(unit) {
|
1230
|
+
case 'year': set['month'] = 11; set['day'] = 31; break;
|
1231
|
+
case 'month': set['day'] = this.daysInMonth(); break;
|
1232
|
+
case 'week': set['weekday'] = 6; break;
|
1233
|
+
}
|
1234
|
+
return this.set(set, true);
|
1235
|
+
};
|
1236
|
+
}
|
1237
|
+
});
|
1238
|
+
date.extend(methods);
|
1239
|
+
}
|
1240
|
+
|
1241
|
+
function buildDateInputFormats() {
|
1242
|
+
DateArgumentUnits = DateUnits.clone().removeAt(2);
|
1243
|
+
DateUnitsReversed = DateUnits.clone().reverse();
|
1244
|
+
var monthReg = '\\d{1,2}|' + English['months'].join('|');
|
1245
|
+
StaticInputFormats.each(function(f) {
|
1246
|
+
addDateInputFormat(f.src.replace(/\{month\}/, monthReg) + (f.time === false ? '' : OptionalTime), f.to.concat(TimeFormat), 'en', f.variant);
|
1247
|
+
});
|
1248
|
+
addDateInputFormat(RequiredTime, TimeFormat);
|
1249
|
+
}
|
1250
|
+
|
1251
|
+
/***
|
1252
|
+
* @method is[Day]()
|
1253
|
+
* @returns Boolean
|
1254
|
+
* @short Returns true if the date falls on that day.
|
1255
|
+
* @extra Also available: %isYesterday%, %isToday%, %isTomorrow%, %isWeekday%, and %isWeekend%.
|
1256
|
+
* @example
|
1257
|
+
*
|
1258
|
+
* Date.create('tomorrow').isToday() -> false
|
1259
|
+
* Date.create('thursday').isTomorrow() -> ?
|
1260
|
+
* Date.create('yesterday').isWednesday() -> ?
|
1261
|
+
* Date.create('today').isWeekend() -> ?
|
1262
|
+
*
|
1263
|
+
***
|
1264
|
+
* @method isToday()
|
1265
|
+
* @set isDay
|
1266
|
+
***
|
1267
|
+
* @method isYesterday()
|
1268
|
+
* @set isDay
|
1269
|
+
***
|
1270
|
+
* @method isTomorrow()
|
1271
|
+
* @set isDay
|
1272
|
+
***
|
1273
|
+
* @method isWeekday()
|
1274
|
+
* @set isDay
|
1275
|
+
***
|
1276
|
+
* @method isWeekend()
|
1277
|
+
* @set isDay
|
1278
|
+
***
|
1279
|
+
* @method isSunday()
|
1280
|
+
* @set isDay
|
1281
|
+
***
|
1282
|
+
* @method isMonday()
|
1283
|
+
* @set isDay
|
1284
|
+
***
|
1285
|
+
* @method isTuesday()
|
1286
|
+
* @set isDay
|
1287
|
+
***
|
1288
|
+
* @method isWednesday()
|
1289
|
+
* @set isDay
|
1290
|
+
***
|
1291
|
+
* @method isThursday()
|
1292
|
+
* @set isDay
|
1293
|
+
***
|
1294
|
+
* @method isFriday()
|
1295
|
+
* @set isDay
|
1296
|
+
***
|
1297
|
+
* @method isSaturday()
|
1298
|
+
* @set isDay
|
1299
|
+
***
|
1300
|
+
* @method isFuture()
|
1301
|
+
* @returns Boolean
|
1302
|
+
* @short Returns true if the date is in the future.
|
1303
|
+
* @example
|
1304
|
+
*
|
1305
|
+
* Date.create('next week').isFuture() -> true
|
1306
|
+
* Date.create('last week').isFuture() -> false
|
1307
|
+
*
|
1308
|
+
***
|
1309
|
+
* @method isPast()
|
1310
|
+
* @returns Boolean
|
1311
|
+
* @short Returns true if the date is in the past.
|
1312
|
+
* @example
|
1313
|
+
*
|
1314
|
+
* Date.create('last week').isPast() -> true
|
1315
|
+
* Date.create('next week').isPast() -> false
|
1316
|
+
*
|
1317
|
+
***/
|
1318
|
+
function buildRelativeAliases() {
|
1319
|
+
var methods = {};
|
1320
|
+
var weekdays = English['weekdays'].slice(0,7);
|
1321
|
+
var months = English['months'].slice(0,12);
|
1322
|
+
['today','yesterday','tomorrow','weekday','weekend','future','past'].concat(weekdays).concat(months).each(function(s) {
|
1323
|
+
methods['is'+ s.capitalize()] = function() {
|
1324
|
+
return this.is(s);
|
1325
|
+
};
|
1326
|
+
});
|
1327
|
+
date.extend(methods);
|
1328
|
+
}
|
1329
|
+
|
1330
|
+
/***
|
1331
|
+
* @method [unit]()
|
1332
|
+
* @returns Number
|
1333
|
+
* @short Takes the number as a corresponding unit of time and converts to milliseconds.
|
1334
|
+
* @extra Method names can be both singular and plural. Note that as "a month" is ambiguous as a unit of time, %months% will be equivalent to 30.4375 days, the average number in a month. Be careful using %months% if you need exact precision.
|
1335
|
+
* @example
|
1336
|
+
*
|
1337
|
+
* (5).milliseconds() -> 5
|
1338
|
+
* (10).hours() -> 36000000
|
1339
|
+
* (1).day() -> 86400000
|
1340
|
+
*
|
1341
|
+
***
|
1342
|
+
* @method millisecond()
|
1343
|
+
* @set unit
|
1344
|
+
***
|
1345
|
+
* @method milliseconds()
|
1346
|
+
* @set unit
|
1347
|
+
***
|
1348
|
+
* @method second()
|
1349
|
+
* @set unit
|
1350
|
+
***
|
1351
|
+
* @method seconds()
|
1352
|
+
* @set unit
|
1353
|
+
***
|
1354
|
+
* @method minute()
|
1355
|
+
* @set unit
|
1356
|
+
***
|
1357
|
+
* @method minutes()
|
1358
|
+
* @set unit
|
1359
|
+
***
|
1360
|
+
* @method hour()
|
1361
|
+
* @set unit
|
1362
|
+
***
|
1363
|
+
* @method hours()
|
1364
|
+
* @set unit
|
1365
|
+
***
|
1366
|
+
* @method day()
|
1367
|
+
* @set unit
|
1368
|
+
***
|
1369
|
+
* @method days()
|
1370
|
+
* @set unit
|
1371
|
+
***
|
1372
|
+
* @method week()
|
1373
|
+
* @set unit
|
1374
|
+
***
|
1375
|
+
* @method weeks()
|
1376
|
+
* @set unit
|
1377
|
+
***
|
1378
|
+
* @method month()
|
1379
|
+
* @set unit
|
1380
|
+
***
|
1381
|
+
* @method months()
|
1382
|
+
* @set unit
|
1383
|
+
***
|
1384
|
+
* @method year()
|
1385
|
+
* @set unit
|
1386
|
+
***
|
1387
|
+
* @method years()
|
1388
|
+
* @set unit
|
1389
|
+
***
|
1390
|
+
* @method [unit]Before([d], [locale] = currentLocale)
|
1391
|
+
* @returns Date
|
1392
|
+
* @short Returns a date that is <n> units before [d], where <n> is the number.
|
1393
|
+
* @extra [d] will accept a date object, timestamp, or text format. Note that "months" is ambiguous as a unit of time. If the target date falls on a day that does not exist (ie. August 31 -> February 31), the date will be shifted to the last day of the month. Be careful using %monthsBefore% if you need exact precision. See @date_format for more information.
|
1394
|
+
* @example
|
1395
|
+
*
|
1396
|
+
* (5).daysBefore('tuesday') -> 5 days before tuesday of this week
|
1397
|
+
* (1).yearBefore('January 23, 1997') -> January 23, 1996
|
1398
|
+
*
|
1399
|
+
***
|
1400
|
+
* @method millisecondBefore()
|
1401
|
+
* @set unitBefore
|
1402
|
+
***
|
1403
|
+
* @method millisecondsBefore()
|
1404
|
+
* @set unitBefore
|
1405
|
+
***
|
1406
|
+
* @method secondBefore()
|
1407
|
+
* @set unitBefore
|
1408
|
+
***
|
1409
|
+
* @method secondsBefore()
|
1410
|
+
* @set unitBefore
|
1411
|
+
***
|
1412
|
+
* @method minuteBefore()
|
1413
|
+
* @set unitBefore
|
1414
|
+
***
|
1415
|
+
* @method minutesBefore()
|
1416
|
+
* @set unitBefore
|
1417
|
+
***
|
1418
|
+
* @method hourBefore()
|
1419
|
+
* @set unitBefore
|
1420
|
+
***
|
1421
|
+
* @method hoursBefore()
|
1422
|
+
* @set unitBefore
|
1423
|
+
***
|
1424
|
+
* @method dayBefore()
|
1425
|
+
* @set unitBefore
|
1426
|
+
***
|
1427
|
+
* @method daysBefore()
|
1428
|
+
* @set unitBefore
|
1429
|
+
***
|
1430
|
+
* @method weekBefore()
|
1431
|
+
* @set unitBefore
|
1432
|
+
***
|
1433
|
+
* @method weeksBefore()
|
1434
|
+
* @set unitBefore
|
1435
|
+
***
|
1436
|
+
* @method monthBefore()
|
1437
|
+
* @set unitBefore
|
1438
|
+
***
|
1439
|
+
* @method monthsBefore()
|
1440
|
+
* @set unitBefore
|
1441
|
+
***
|
1442
|
+
* @method yearBefore()
|
1443
|
+
* @set unitBefore
|
1444
|
+
***
|
1445
|
+
* @method yearsBefore()
|
1446
|
+
* @set unitBefore
|
1447
|
+
***
|
1448
|
+
* @method [unit]Ago()
|
1449
|
+
* @returns Date
|
1450
|
+
* @short Returns a date that is <n> units ago.
|
1451
|
+
* @extra Note that "months" is ambiguous as a unit of time. If the target date falls on a day that does not exist (ie. August 31 -> February 31), the date will be shifted to the last day of the month. Be careful using %monthsAgo% if you need exact precision.
|
1452
|
+
* @example
|
1453
|
+
*
|
1454
|
+
* (5).weeksAgo() -> 5 weeks ago
|
1455
|
+
* (1).yearAgo() -> January 23, 1996
|
1456
|
+
*
|
1457
|
+
***
|
1458
|
+
* @method millisecondAgo()
|
1459
|
+
* @set unitAgo
|
1460
|
+
***
|
1461
|
+
* @method millisecondsAgo()
|
1462
|
+
* @set unitAgo
|
1463
|
+
***
|
1464
|
+
* @method secondAgo()
|
1465
|
+
* @set unitAgo
|
1466
|
+
***
|
1467
|
+
* @method secondsAgo()
|
1468
|
+
* @set unitAgo
|
1469
|
+
***
|
1470
|
+
* @method minuteAgo()
|
1471
|
+
* @set unitAgo
|
1472
|
+
***
|
1473
|
+
* @method minutesAgo()
|
1474
|
+
* @set unitAgo
|
1475
|
+
***
|
1476
|
+
* @method hourAgo()
|
1477
|
+
* @set unitAgo
|
1478
|
+
***
|
1479
|
+
* @method hoursAgo()
|
1480
|
+
* @set unitAgo
|
1481
|
+
***
|
1482
|
+
* @method dayAgo()
|
1483
|
+
* @set unitAgo
|
1484
|
+
***
|
1485
|
+
* @method daysAgo()
|
1486
|
+
* @set unitAgo
|
1487
|
+
***
|
1488
|
+
* @method weekAgo()
|
1489
|
+
* @set unitAgo
|
1490
|
+
***
|
1491
|
+
* @method weeksAgo()
|
1492
|
+
* @set unitAgo
|
1493
|
+
***
|
1494
|
+
* @method monthAgo()
|
1495
|
+
* @set unitAgo
|
1496
|
+
***
|
1497
|
+
* @method monthsAgo()
|
1498
|
+
* @set unitAgo
|
1499
|
+
***
|
1500
|
+
* @method yearAgo()
|
1501
|
+
* @set unitAgo
|
1502
|
+
***
|
1503
|
+
* @method yearsAgo()
|
1504
|
+
* @set unitAgo
|
1505
|
+
***
|
1506
|
+
* @method [unit]After([d], [locale] = currentLocale)
|
1507
|
+
* @returns Date
|
1508
|
+
* @short Returns a date <n> units after [d], where <n> is the number.
|
1509
|
+
* @extra [d] will accept a date object, timestamp, or text format. Note that "months" is ambiguous as a unit of time. If the target date falls on a day that does not exist (ie. August 31 -> February 31), the date will be shifted to the last day of the month. Be careful using %monthsAfter% if you need exact precision. See @date_format for more information.
|
1510
|
+
* @example
|
1511
|
+
*
|
1512
|
+
* (5).daysAfter('tuesday') -> 5 days after tuesday of this week
|
1513
|
+
* (1).yearAfter('January 23, 1997') -> January 23, 1998
|
1514
|
+
*
|
1515
|
+
***
|
1516
|
+
* @method millisecondAfter()
|
1517
|
+
* @set unitAfter
|
1518
|
+
***
|
1519
|
+
* @method millisecondsAfter()
|
1520
|
+
* @set unitAfter
|
1521
|
+
***
|
1522
|
+
* @method secondAfter()
|
1523
|
+
* @set unitAfter
|
1524
|
+
***
|
1525
|
+
* @method secondsAfter()
|
1526
|
+
* @set unitAfter
|
1527
|
+
***
|
1528
|
+
* @method minuteAfter()
|
1529
|
+
* @set unitAfter
|
1530
|
+
***
|
1531
|
+
* @method minutesAfter()
|
1532
|
+
* @set unitAfter
|
1533
|
+
***
|
1534
|
+
* @method hourAfter()
|
1535
|
+
* @set unitAfter
|
1536
|
+
***
|
1537
|
+
* @method hoursAfter()
|
1538
|
+
* @set unitAfter
|
1539
|
+
***
|
1540
|
+
* @method dayAfter()
|
1541
|
+
* @set unitAfter
|
1542
|
+
***
|
1543
|
+
* @method daysAfter()
|
1544
|
+
* @set unitAfter
|
1545
|
+
***
|
1546
|
+
* @method weekAfter()
|
1547
|
+
* @set unitAfter
|
1548
|
+
***
|
1549
|
+
* @method weeksAfter()
|
1550
|
+
* @set unitAfter
|
1551
|
+
***
|
1552
|
+
* @method monthAfter()
|
1553
|
+
* @set unitAfter
|
1554
|
+
***
|
1555
|
+
* @method monthsAfter()
|
1556
|
+
* @set unitAfter
|
1557
|
+
***
|
1558
|
+
* @method yearAfter()
|
1559
|
+
* @set unitAfter
|
1560
|
+
***
|
1561
|
+
* @method yearsAfter()
|
1562
|
+
* @set unitAfter
|
1563
|
+
***
|
1564
|
+
* @method [unit]FromNow()
|
1565
|
+
* @returns Date
|
1566
|
+
* @short Returns a date <n> units from now.
|
1567
|
+
* @extra Note that "months" is ambiguous as a unit of time. If the target date falls on a day that does not exist (ie. August 31 -> February 31), the date will be shifted to the last day of the month. Be careful using %monthsFromNow% if you need exact precision.
|
1568
|
+
* @example
|
1569
|
+
*
|
1570
|
+
* (5).weeksFromNow() -> 5 weeks ago
|
1571
|
+
* (1).yearFromNow() -> January 23, 1998
|
1572
|
+
*
|
1573
|
+
***
|
1574
|
+
* @method millisecondFromNow()
|
1575
|
+
* @set unitFromNow
|
1576
|
+
***
|
1577
|
+
* @method millisecondsFromNow()
|
1578
|
+
* @set unitFromNow
|
1579
|
+
***
|
1580
|
+
* @method secondFromNow()
|
1581
|
+
* @set unitFromNow
|
1582
|
+
***
|
1583
|
+
* @method secondsFromNow()
|
1584
|
+
* @set unitFromNow
|
1585
|
+
***
|
1586
|
+
* @method minuteFromNow()
|
1587
|
+
* @set unitFromNow
|
1588
|
+
***
|
1589
|
+
* @method minutesFromNow()
|
1590
|
+
* @set unitFromNow
|
1591
|
+
***
|
1592
|
+
* @method hourFromNow()
|
1593
|
+
* @set unitFromNow
|
1594
|
+
***
|
1595
|
+
* @method hoursFromNow()
|
1596
|
+
* @set unitFromNow
|
1597
|
+
***
|
1598
|
+
* @method dayFromNow()
|
1599
|
+
* @set unitFromNow
|
1600
|
+
***
|
1601
|
+
* @method daysFromNow()
|
1602
|
+
* @set unitFromNow
|
1603
|
+
***
|
1604
|
+
* @method weekFromNow()
|
1605
|
+
* @set unitFromNow
|
1606
|
+
***
|
1607
|
+
* @method weeksFromNow()
|
1608
|
+
* @set unitFromNow
|
1609
|
+
***
|
1610
|
+
* @method monthFromNow()
|
1611
|
+
* @set unitFromNow
|
1612
|
+
***
|
1613
|
+
* @method monthsFromNow()
|
1614
|
+
* @set unitFromNow
|
1615
|
+
***
|
1616
|
+
* @method yearFromNow()
|
1617
|
+
* @set unitFromNow
|
1618
|
+
***
|
1619
|
+
* @method yearsFromNow()
|
1620
|
+
* @set unitFromNow
|
1621
|
+
***/
|
1622
|
+
function buildNumberToDateAlias(unit, multiplier) {
|
1623
|
+
var add = 'add' + unit.capitalize() + 's', methods = {};
|
1624
|
+
function base() { return (this * multiplier).round(); }
|
1625
|
+
function after() { return createDate(arguments)[add](this); }
|
1626
|
+
function before() { return createDate(arguments)[add](-this); }
|
1627
|
+
methods[unit] = base;
|
1628
|
+
methods[unit + 's'] = base;
|
1629
|
+
methods[unit + 'Before'] = before;
|
1630
|
+
methods[unit + 'sBefore'] = before;
|
1631
|
+
methods[unit + 'Ago'] = before;
|
1632
|
+
methods[unit + 'sAgo'] = before;
|
1633
|
+
methods[unit + 'After'] = after;
|
1634
|
+
methods[unit + 'sAfter'] = after;
|
1635
|
+
methods[unit + 'FromNow'] = after;
|
1636
|
+
methods[unit + 'sFromNow'] = after;
|
1637
|
+
number.extend(methods);
|
1638
|
+
}
|
1639
|
+
|
1640
|
+
function setDateProperties() {
|
1641
|
+
date.extend({
|
1642
|
+
'DSTOffset': (new date(2000, 6, 1).getTimezoneOffset() - new date(2000, 0, 1).getTimezoneOffset()) * 60 * 1000,
|
1643
|
+
'INTERNATIONAL_TIME': '{h}:{mm}:{ss}',
|
1644
|
+
'RFC1123': '{Dow}, {dd} {Mon} {yyyy} {HH}:{mm}:{ss} {tz}',
|
1645
|
+
'RFC1036': '{Weekday}, {dd}-{Mon}-{yy} {HH}:{mm}:{ss} {tz}',
|
1646
|
+
'ISO8601_DATE': '{yyyy}-{MM}-{dd}',
|
1647
|
+
'ISO8601_DATETIME': '{yyyy}-{MM}-{dd}T{HH}:{mm}:{ss}.{fff}{isotz}'
|
1648
|
+
}, false, false);
|
1649
|
+
}
|
1650
|
+
|
1651
|
+
|
1652
|
+
/***
|
1653
|
+
* @method toISOString()
|
1654
|
+
* @returns String
|
1655
|
+
* @short Formats the string to ISO8601 format.
|
1656
|
+
* @extra This will always format as UTC time. Provided for browsers that do not support this method.
|
1657
|
+
* @example
|
1658
|
+
*
|
1659
|
+
* Date.create().toISOString() -> ex. 2011-07-05 12:24:55.528Z
|
1660
|
+
*
|
1661
|
+
***
|
1662
|
+
* @method toJSON()
|
1663
|
+
* @returns String
|
1664
|
+
* @short Returns a JSON representation of the date.
|
1665
|
+
* @extra This is effectively an alias for %toISOString%. Will always return the date in UTC time. Implemented for browsers that do not support it.
|
1666
|
+
* @example
|
1667
|
+
*
|
1668
|
+
* Date.create().toJSON() -> ex. 2011-07-05 12:24:55.528Z
|
1669
|
+
*
|
1670
|
+
***/
|
1671
|
+
|
1672
|
+
function buildISOString(name) {
|
1673
|
+
var d = new date(date.UTC(1999, 11, 31)), target = '1999-12-31T00:00:00.000Z', methods = {};
|
1674
|
+
if(!d[name] || d[name]() !== target) {
|
1675
|
+
methods[name] = function() { return formatDate(this.toUTC(), date['ISO8601_DATETIME']); }
|
1676
|
+
date.extend(methods, true);
|
1677
|
+
}
|
1678
|
+
}
|
1679
|
+
|
1680
|
+
function buildDate() {
|
1681
|
+
English = date.setLocale('en');
|
1682
|
+
buildDateMethods();
|
1683
|
+
buildDateInputFormats();
|
1684
|
+
buildRelativeAliases();
|
1685
|
+
buildISOString('toISOString');
|
1686
|
+
buildISOString('toJSON');
|
1687
|
+
setDateProperties();
|
1688
|
+
}
|
1689
|
+
|
1690
|
+
|
1691
|
+
date.extend({
|
1692
|
+
|
1693
|
+
/***
|
1694
|
+
* @method Date.create(<d>, [locale] = currentLocale)
|
1695
|
+
* @returns Date
|
1696
|
+
* @short Alternate Date constructor which understands various formats.
|
1697
|
+
* @extra Accepts a multitude of text formats, a timestamp, or another date. If no argument is given, date is assumed to be now. %Date.create% additionally can accept enumerated parameters as with the standard date constructor. [locale] can be passed to specify the locale that the date is in. For more information, see @date_format.
|
1698
|
+
* @example
|
1699
|
+
*
|
1700
|
+
* Date.create('July') -> July of this year
|
1701
|
+
* Date.create('1776') -> 1776
|
1702
|
+
* Date.create('today') -> today
|
1703
|
+
* Date.create('wednesday') -> This wednesday
|
1704
|
+
* Date.create('next friday') -> Next friday
|
1705
|
+
* Date.create('July 4, 1776') -> July 4, 1776
|
1706
|
+
* Date.create(-446806800000) -> November 5, 1955
|
1707
|
+
* Date.create(1776, 6, 4) -> July 4, 1776
|
1708
|
+
* Date.create('1776年07月04日', 'ja') -> July 4, 1776
|
1709
|
+
*
|
1710
|
+
***/
|
1711
|
+
'create': function() {
|
1712
|
+
return createDate(arguments);
|
1713
|
+
},
|
1714
|
+
|
1715
|
+
/***
|
1716
|
+
* @method Date.now()
|
1717
|
+
* @returns String
|
1718
|
+
* @short Returns the number of milliseconds since January 1st, 1970 00:00:00 (UTC time).
|
1719
|
+
* @example
|
1720
|
+
*
|
1721
|
+
* Date.now() -> ex. 1311938296231
|
1722
|
+
*
|
1723
|
+
***/
|
1724
|
+
'now': function() {
|
1725
|
+
return new date().getTime();
|
1726
|
+
},
|
1727
|
+
|
1728
|
+
/***
|
1729
|
+
* @method Date.setLocale(<code>, [set])
|
1730
|
+
* @returns Locale
|
1731
|
+
* @short Sets the current locale to be used with dates.
|
1732
|
+
* @extra Predefined locales are: English (en), French (fr), Italian (it), Spanish (es), Portuguese (pt), German (de), Russian (ru), Japanese (ja), Korean (ko), Simplified Chinese (zh-CN), and Traditional Chinese (zh-TW). In addition to available major locales, you can define a new local here by passing an object for [set]. For more see @date_format.
|
1733
|
+
*
|
1734
|
+
***/
|
1735
|
+
'setLocale': function(code, set) {
|
1736
|
+
var loc = getLocalization(code, false, set);
|
1737
|
+
if(loc) {
|
1738
|
+
Date['currentLocale'] = code;
|
1739
|
+
checkLocaleFormatsAdded(loc);
|
1740
|
+
return loc;
|
1741
|
+
}
|
1742
|
+
},
|
1743
|
+
|
1744
|
+
/***
|
1745
|
+
* @method Date.getLocale([code] = current)
|
1746
|
+
* @returns Locale
|
1747
|
+
* @short Gets the locale for the given code, or the current locale.
|
1748
|
+
* @extra Returns undefined if there is no locale for the given code. Manipulating the locale object can give you more control over date localizations. For more about locales, see @date_format.
|
1749
|
+
*
|
1750
|
+
***/
|
1751
|
+
'getLocale': function(code) {
|
1752
|
+
return getLocalization(code, true);
|
1753
|
+
},
|
1754
|
+
|
1755
|
+
/***
|
1756
|
+
* @method Date.addFormat(<format>, <match>, [locale] = null)
|
1757
|
+
* @returns Nothing
|
1758
|
+
* @short Manually adds a new date input format.
|
1759
|
+
* @extra This method allows fine grained control for alternate formats. <format> is a string that can have regex tokens inside. <match> is an array of the tokens that each regex capturing group will map to, for example %year%, %date%, etc. For more, see @date_format.
|
1760
|
+
*
|
1761
|
+
***/
|
1762
|
+
'addFormat': function(format, match, locale, variant) {
|
1763
|
+
addDateInputFormat(format, match, locale, variant, 'unshift');
|
1764
|
+
}
|
1765
|
+
|
1766
|
+
}, false, false);
|
1767
|
+
|
1768
|
+
date.extend({
|
1769
|
+
|
1770
|
+
/***
|
1771
|
+
* @method set(<set>, [reset] = false)
|
1772
|
+
* @returns Date
|
1773
|
+
* @short Sets the date object.
|
1774
|
+
* @extra This method can accept multiple formats including a single number as a timestamp, an object, or enumerated parameters (as with the Date constructor). If [reset] is %true%, any units more specific than those passed will be reset. %setUTC% will set the date according to universal time.
|
1775
|
+
* @example
|
1776
|
+
*
|
1777
|
+
* new Date().set({ year: 2011, month: 11, day: 31 }) -> December 31, 2011
|
1778
|
+
* new Date().set(2011, 11, 31) -> December 31, 2011
|
1779
|
+
* new Date().set(86400000) -> 1 day after Jan 1, 1970
|
1780
|
+
* new Date().set({ year: 2004, month: 6 }, true) -> June 1, 2004, 00:00:00.000
|
1781
|
+
*
|
1782
|
+
***/
|
1783
|
+
'set': function() {
|
1784
|
+
var args = collectDateArguments(arguments);
|
1785
|
+
return updateDate(this, args[0], args[1])
|
1786
|
+
},
|
1787
|
+
|
1788
|
+
/***
|
1789
|
+
* @method setUTC()
|
1790
|
+
* @set set
|
1791
|
+
***/
|
1792
|
+
'setUTC': function() {
|
1793
|
+
var args = collectDateArguments(arguments);
|
1794
|
+
return updateDate(this, args[0], args[1], true)
|
1795
|
+
},
|
1796
|
+
|
1797
|
+
/***
|
1798
|
+
* @method setWeekday()
|
1799
|
+
* @returns Nothing
|
1800
|
+
* @short Sets the weekday of the date.
|
1801
|
+
* @extra %setUTCWeekday% sets according to universal time.
|
1802
|
+
* @example
|
1803
|
+
*
|
1804
|
+
* d = new Date(); d.setWeekday(1); d; -> Monday of this week
|
1805
|
+
* d = new Date(); d.setWeekday(6); d; -> Saturday of this week
|
1806
|
+
*
|
1807
|
+
***/
|
1808
|
+
'setWeekday': function(dow) {
|
1809
|
+
if(isUndefined(dow)) return;
|
1810
|
+
this.setDate(this.getDate() + dow - this.getDay());
|
1811
|
+
},
|
1812
|
+
|
1813
|
+
/***
|
1814
|
+
* @method setUTCWeekday()
|
1815
|
+
* @set setWeekday
|
1816
|
+
***/
|
1817
|
+
'setUTCWeekday': function(dow) {
|
1818
|
+
if(isUndefined(dow)) return;
|
1819
|
+
this.setDate(this.getUTCDate() + dow - this.getDay());
|
1820
|
+
},
|
1821
|
+
|
1822
|
+
/***
|
1823
|
+
* @method setWeek()
|
1824
|
+
* @returns Nothing
|
1825
|
+
* @short Sets the week (of the year).
|
1826
|
+
* @extra %setUTCWeek% sets according to universal time.
|
1827
|
+
* @example
|
1828
|
+
*
|
1829
|
+
* d = new Date(); d.setWeek(15); d; -> 15th week of the year
|
1830
|
+
*
|
1831
|
+
***/
|
1832
|
+
'setWeek': function(week) {
|
1833
|
+
if(isUndefined(week)) return;
|
1834
|
+
var date = this.getDate();
|
1835
|
+
this.setMonth(0);
|
1836
|
+
this.setDate((week * 7) + 1);
|
1837
|
+
},
|
1838
|
+
|
1839
|
+
/***
|
1840
|
+
* @method setUTCWeek()
|
1841
|
+
* @set setWeek
|
1842
|
+
***/
|
1843
|
+
'setUTCWeek': function(week) {
|
1844
|
+
if(isUndefined(week)) return;
|
1845
|
+
var date = this.getUTCDate();
|
1846
|
+
this.setMonth(0);
|
1847
|
+
this.setUTCDate((week * 7) + 1);
|
1848
|
+
},
|
1849
|
+
|
1850
|
+
/***
|
1851
|
+
* @method getWeek()
|
1852
|
+
* @returns Number
|
1853
|
+
* @short Gets the date's week (of the year).
|
1854
|
+
* @extra %getUTCWeek% gets the time according to universal time.
|
1855
|
+
* @example
|
1856
|
+
*
|
1857
|
+
* new Date().getWeek() -> today's week of the year
|
1858
|
+
*
|
1859
|
+
***/
|
1860
|
+
'getWeek': function() {
|
1861
|
+
return getWeekNumber(this);
|
1862
|
+
},
|
1863
|
+
|
1864
|
+
/***
|
1865
|
+
* @method getUTCWeek()
|
1866
|
+
* @set getWeek
|
1867
|
+
***/
|
1868
|
+
'getUTCWeek': function() {
|
1869
|
+
return getWeekNumber(this.toUTC());
|
1870
|
+
},
|
1871
|
+
|
1872
|
+
/***
|
1873
|
+
* @method getUTCOffset([iso])
|
1874
|
+
* @returns String
|
1875
|
+
* @short Returns a string representation of the offset from UTC time. If [iso] is true the offset will be in ISO8601 format.
|
1876
|
+
* @example
|
1877
|
+
*
|
1878
|
+
* new Date().getUTCOffset() -> "+0900"
|
1879
|
+
* new Date().getUTCOffset(true) -> "+09:00"
|
1880
|
+
*
|
1881
|
+
***/
|
1882
|
+
'getUTCOffset': function(iso) {
|
1883
|
+
var offset = this.utc ? 0 : this.getTimezoneOffset();
|
1884
|
+
var colon = iso === true ? ':' : '';
|
1885
|
+
if(!offset && iso) return 'Z';
|
1886
|
+
return (-offset / 60).round().pad(2, true) + colon + (offset % 60).pad(2);
|
1887
|
+
},
|
1888
|
+
|
1889
|
+
/***
|
1890
|
+
* @method toUTC()
|
1891
|
+
* @returns Date
|
1892
|
+
* @short Converts the date to UTC time, effectively subtracting the timezone offset.
|
1893
|
+
* @extra Note here that the method %getTimezoneOffset% will still show an offset even after this method is called, as this method effectively just rewinds the date. %format% however, will correctly set the %{tz}% (timezone) token as UTC once this method has been called on the date. Once a date is set to UTC the only way to unset is the %clone% method.
|
1894
|
+
* @example
|
1895
|
+
*
|
1896
|
+
* new Date().toUTC() -> current time in UTC
|
1897
|
+
*
|
1898
|
+
***/
|
1899
|
+
'toUTC': function() {
|
1900
|
+
if(this.utc) return this;
|
1901
|
+
var d = this.clone().addMinutes(this.getTimezoneOffset());
|
1902
|
+
d.utc = true;
|
1903
|
+
return d;
|
1904
|
+
},
|
1905
|
+
|
1906
|
+
/***
|
1907
|
+
* @method isUTC()
|
1908
|
+
* @returns Boolean
|
1909
|
+
* @short Returns true if the date has no timezone offset.
|
1910
|
+
* @example
|
1911
|
+
*
|
1912
|
+
* new Date().isUTC() -> true or false?
|
1913
|
+
*
|
1914
|
+
***/
|
1915
|
+
'isUTC': function() {
|
1916
|
+
return this.utc || this.getTimezoneOffset() === 0;
|
1917
|
+
},
|
1918
|
+
|
1919
|
+
/***
|
1920
|
+
* @method advance()
|
1921
|
+
* @returns Date
|
1922
|
+
* @short Sets the date forward.
|
1923
|
+
* @extra This method can accept multiple formats including a single number as a timestamp, an object, or enumerated parameters (as with the Date constructor). For more see @date_format.
|
1924
|
+
* @example
|
1925
|
+
*
|
1926
|
+
* new Date().advance({ year: 2 }) -> 2 years in the future
|
1927
|
+
* new Date().advance(0, 2, 3) -> 2 months 3 days in the future
|
1928
|
+
* new Date().advance(86400000) -> 1 day in the future
|
1929
|
+
*
|
1930
|
+
***/
|
1931
|
+
'advance': function(params) {
|
1932
|
+
var args = collectDateArguments(arguments);
|
1933
|
+
return updateDate(this, args[0], false, false, 1, true);
|
1934
|
+
},
|
1935
|
+
|
1936
|
+
/***
|
1937
|
+
* @method rewind()
|
1938
|
+
* @returns Date
|
1939
|
+
* @short Sets the date back.
|
1940
|
+
* @extra This method can accept multiple formats including a single number as a timestamp, an object, or enumerated parameters (as with the Date constructor). For more see @date_format.
|
1941
|
+
* @example
|
1942
|
+
*
|
1943
|
+
* new Date().rewind({ year: 2 }) -> 2 years in the past
|
1944
|
+
* new Date().rewind(0, 2, 3) -> 2 months 3 days in the past
|
1945
|
+
* new Date().rewind(86400000) -> 1 day in the past
|
1946
|
+
*
|
1947
|
+
***/
|
1948
|
+
'rewind': function(params) {
|
1949
|
+
var args = collectDateArguments(arguments);
|
1950
|
+
return updateDate(this, args[0], false, false, -1);
|
1951
|
+
},
|
1952
|
+
|
1953
|
+
/***
|
1954
|
+
* @method isValid()
|
1955
|
+
* @returns Boolean
|
1956
|
+
* @short Returns true if the date is valid.
|
1957
|
+
* @example
|
1958
|
+
*
|
1959
|
+
* new Date().isValid() -> true
|
1960
|
+
* new Date('flexor').isValid() -> false
|
1961
|
+
*
|
1962
|
+
***/
|
1963
|
+
'isValid': function() {
|
1964
|
+
return !isNaN(this.getTime());
|
1965
|
+
},
|
1966
|
+
|
1967
|
+
/***
|
1968
|
+
* @method isAfter(<d>, [margin])
|
1969
|
+
* @returns Boolean
|
1970
|
+
* @short Returns true if the date is after the <d>.
|
1971
|
+
* @extra [margin] is to allow extra margin of error (in ms). <d> will accept a date object, timestamp, or text format. If not specified, <d> is assumed to be now. See @date_format for more information.
|
1972
|
+
* @example
|
1973
|
+
*
|
1974
|
+
* new Date().isAfter('tomorrow') -> false
|
1975
|
+
* new Date().isAfter('yesterday') -> true
|
1976
|
+
*
|
1977
|
+
***/
|
1978
|
+
'isAfter': function(d, margin) {
|
1979
|
+
return this.getTime() > date.create(d).getTime() - (margin || 0);
|
1980
|
+
},
|
1981
|
+
|
1982
|
+
/***
|
1983
|
+
* @method isBefore(<d>, [margin])
|
1984
|
+
* @returns Boolean
|
1985
|
+
* @short Returns true if the date is before <d>.
|
1986
|
+
* @extra [margin] is to allow extra margin of error (in ms). <d> will accept a date object, timestamp, or text format. If not specified, <d> is assumed to be now. See @date_format for more information.
|
1987
|
+
* @example
|
1988
|
+
*
|
1989
|
+
* new Date().isBefore('tomorrow') -> true
|
1990
|
+
* new Date().isBefore('yesterday') -> false
|
1991
|
+
*
|
1992
|
+
***/
|
1993
|
+
'isBefore': function(d, margin) {
|
1994
|
+
return this.getTime() < date.create(d).getTime() + (margin || 0);
|
1995
|
+
},
|
1996
|
+
|
1997
|
+
/***
|
1998
|
+
* @method isBetween(<d1>, <d2>, [buffer] = 0)
|
1999
|
+
* @returns Boolean
|
2000
|
+
* @short Returns true if the date falls between <d1> and <d2>.
|
2001
|
+
* @extra [buffer] is to allow extra buffer of error (in ms). <d1> and <d2> will accept a date object, timestamp, or text format. If not specified, they are assumed to be now. See @date_format for more information.
|
2002
|
+
* @example
|
2003
|
+
*
|
2004
|
+
* new Date().isBetween('yesterday', 'tomorrow') -> true
|
2005
|
+
* new Date().isBetween('last year', '2 years ago') -> false
|
2006
|
+
*
|
2007
|
+
***/
|
2008
|
+
'isBetween': function(d1, d2, buffer) {
|
2009
|
+
var t = this.getTime();
|
2010
|
+
var t1 = date.create(d1).getTime();
|
2011
|
+
var t2 = date.create(d2).getTime();
|
2012
|
+
var lo = Math.min(t1, t2);
|
2013
|
+
var hi = Math.max(t1, t2);
|
2014
|
+
buffer = buffer || 0;
|
2015
|
+
return (lo - buffer < t) && (hi + buffer > t);
|
2016
|
+
},
|
2017
|
+
|
2018
|
+
/***
|
2019
|
+
* @method isLeapYear()
|
2020
|
+
* @returns Boolean
|
2021
|
+
* @short Returns true if the date is a leap year.
|
2022
|
+
* @example
|
2023
|
+
*
|
2024
|
+
* Date.create('2000').isLeapYear() -> true
|
2025
|
+
*
|
2026
|
+
***/
|
2027
|
+
'isLeapYear': function() {
|
2028
|
+
var year = this.getFullYear();
|
2029
|
+
return (year % 4 === 0 && year % 100 !== 0) || (year % 400 === 0);
|
2030
|
+
},
|
2031
|
+
|
2032
|
+
/***
|
2033
|
+
* @method daysInMonth()
|
2034
|
+
* @returns Number
|
2035
|
+
* @short Returns the number of days in the date's month.
|
2036
|
+
* @example
|
2037
|
+
*
|
2038
|
+
* Date.create('May').daysInMonth() -> 31
|
2039
|
+
* Date.create('February, 2000').daysInMonth() -> 29
|
2040
|
+
*
|
2041
|
+
***/
|
2042
|
+
'daysInMonth': function() {
|
2043
|
+
return 32 - new date(this.getFullYear(), this.getMonth(), 32).getDate();
|
2044
|
+
},
|
2045
|
+
|
2046
|
+
/***
|
2047
|
+
* @method format(<format>, [locale] = currentLocale)
|
2048
|
+
* @returns String
|
2049
|
+
* @short Formats the date.
|
2050
|
+
* @extra <format> will accept a number of tokens as well as pre-determined formats. [locale] specifies a locale code to use (if not specified the current locale is used). If <format> is falsy, a default format for the locale is used. A function may also be passed here to allow more granular control. See @date_format for more details.
|
2051
|
+
* @example
|
2052
|
+
*
|
2053
|
+
* Date.create().format() -> ex. July 4, 2003
|
2054
|
+
* Date.create().format('{Weekday} {d} {Month}, {yyyy}') -> ex. Monday July 4, 2003
|
2055
|
+
* Date.create().format('{hh}:{mm}') -> ex. 15:57
|
2056
|
+
* Date.create().format('{12hr}:{mm}{tt}') -> ex. 3:57pm
|
2057
|
+
* Date.create().format(Date.ISO8601_DATETIME) -> ex. 2011-07-05 12:24:55.528Z
|
2058
|
+
* Date.create('last week').format('', 'ja') -> ex. 先週
|
2059
|
+
* Date.create('yesterday').format(function(value,unit,ms,loc) {
|
2060
|
+
* // value = 1, unit = 3, ms = -86400000, loc = [current locale object]
|
2061
|
+
* }); -> ex. 1 day ago
|
2062
|
+
*
|
2063
|
+
***/
|
2064
|
+
'format': function(f, locale) {
|
2065
|
+
return formatDate(this, f, false, locale);
|
2066
|
+
},
|
2067
|
+
|
2068
|
+
/***
|
2069
|
+
* @method relative([fn], [locale] = currentLocale)
|
2070
|
+
* @returns String
|
2071
|
+
* @short Returns a relative date string offset to the current time.
|
2072
|
+
* @extra [fn] can be passed to provide for more granular control over the resulting string. [fn] is passed 4 arguments: the adjusted value, unit, offset in milliseconds, and a localization object. As an alternate syntax, [locale] can also be passed as the first (and only) parameter. For more information, see @date_format.
|
2073
|
+
* @example
|
2074
|
+
*
|
2075
|
+
* Date.create('90 seconds ago').relative() -> 1 minute ago
|
2076
|
+
* Date.create('January').relative() -> ex. 5 months ago
|
2077
|
+
* Date.create('January').relative('ja') -> 3ヶ月前
|
2078
|
+
* Date.create('120 minutes ago').relative(function(val,unit,ms,loc) {
|
2079
|
+
* // value = 2, unit = 3, ms = -7200, loc = [current locale object]
|
2080
|
+
* }); -> ex. 5 months ago
|
2081
|
+
*
|
2082
|
+
***/
|
2083
|
+
'relative': function(f, locale) {
|
2084
|
+
if(object.isString(f)) {
|
2085
|
+
locale = f;
|
2086
|
+
f = null;
|
2087
|
+
}
|
2088
|
+
return formatDate(this, f, true, locale);
|
2089
|
+
},
|
2090
|
+
|
2091
|
+
/***
|
2092
|
+
* @method is(<d>, [margin])
|
2093
|
+
* @returns Boolean
|
2094
|
+
* @short Returns true if the date is <d>.
|
2095
|
+
* @extra <d> will accept a date object, timestamp, or text format. %is% additionally understands more generalized expressions like month/weekday names, 'today', etc, and compares to the precision implied in <d>. [margin] allows an extra margin of error in milliseconds. For more information, see @date_format.
|
2096
|
+
* @example
|
2097
|
+
*
|
2098
|
+
* Date.create().is('July') -> true or false?
|
2099
|
+
* Date.create().is('1776') -> false
|
2100
|
+
* Date.create().is('today') -> true
|
2101
|
+
* Date.create().is('weekday') -> true or false?
|
2102
|
+
* Date.create().is('July 4, 1776') -> false
|
2103
|
+
* Date.create().is(-6106093200000) -> false
|
2104
|
+
* Date.create().is(new Date(1776, 6, 4)) -> false
|
2105
|
+
*
|
2106
|
+
***/
|
2107
|
+
'is': function(d, margin) {
|
2108
|
+
var tmp;
|
2109
|
+
if(object.isString(d)) {
|
2110
|
+
d = d.trim().toLowerCase();
|
2111
|
+
switch(true) {
|
2112
|
+
case d === 'future': return this.getTime() > new date().getTime();
|
2113
|
+
case d === 'past': return this.getTime() < new date().getTime();
|
2114
|
+
case d === 'weekday': return this.getDay() > 0 && this.getDay() < 6;
|
2115
|
+
case d === 'weekend': return this.getDay() === 0 || this.getDay() === 6;
|
2116
|
+
case (tmp = English['weekdays'].indexOf(d) % 7) > -1: return this.getDay() === tmp;
|
2117
|
+
case (tmp = English['months'].indexOf(d) % 12) > -1: return this.getMonth() === tmp;
|
2118
|
+
}
|
2119
|
+
}
|
2120
|
+
return compareDate(this, d, margin);
|
2121
|
+
},
|
2122
|
+
|
2123
|
+
/***
|
2124
|
+
* @method resetTime()
|
2125
|
+
* @returns Date
|
2126
|
+
* @short Resets the time in the date to 00:00:00.000.
|
2127
|
+
* @example
|
2128
|
+
*
|
2129
|
+
* Date.create().resetTime() -> Beginning of today
|
2130
|
+
*
|
2131
|
+
***/
|
2132
|
+
'resetTime': function() {
|
2133
|
+
return this.set({ 'hour': 0, 'minute': 0, 'second': 0, 'millisecond': 0 });
|
2134
|
+
},
|
2135
|
+
|
2136
|
+
/***
|
2137
|
+
* @method clone()
|
2138
|
+
* @returns Date
|
2139
|
+
* @short Clones the date.
|
2140
|
+
* @example
|
2141
|
+
*
|
2142
|
+
* Date.create().clone() -> Copy of now
|
2143
|
+
*
|
2144
|
+
***/
|
2145
|
+
'clone': function() {
|
2146
|
+
return new date(this.getTime());
|
2147
|
+
}
|
2148
|
+
|
2149
|
+
});
|
2150
|
+
|
2151
|
+
|
2152
|
+
// Instance aliases
|
2153
|
+
date.extend({
|
2154
|
+
|
2155
|
+
/***
|
2156
|
+
* @method iso()
|
2157
|
+
* @alias toISOString
|
2158
|
+
*
|
2159
|
+
***/
|
2160
|
+
'iso': function() {
|
2161
|
+
return this.toISOString();
|
2162
|
+
},
|
2163
|
+
|
2164
|
+
/***
|
2165
|
+
* @method getWeekday()
|
2166
|
+
* @alias getDay
|
2167
|
+
*
|
2168
|
+
***/
|
2169
|
+
'getWeekday': date.prototype.getDay,
|
2170
|
+
|
2171
|
+
/***
|
2172
|
+
* @method getUTCWeekday()
|
2173
|
+
* @alias getUTCDay
|
2174
|
+
*
|
2175
|
+
***/
|
2176
|
+
'getUTCWeekday': date.prototype.getUTCDay
|
2177
|
+
|
2178
|
+
});
|
2179
|
+
|
2180
|
+
|
2181
|
+
|
2182
|
+
/***
|
2183
|
+
* Number module
|
2184
|
+
*
|
2185
|
+
***/
|
2186
|
+
|
2187
|
+
number.extend({
|
2188
|
+
|
2189
|
+
/***
|
2190
|
+
* @method duration([locale] = currentLocale)
|
2191
|
+
* @returns String
|
2192
|
+
* @short Takes the number as milliseconds and returns a unit-adjusted localized string.
|
2193
|
+
* @extra This method is the same as %Date#relative% without the localized equivalent of "from now" or "ago". [locale] can be passed as the first (and only) parameter. Note that this method is only available when the dates package is included.
|
2194
|
+
* @example
|
2195
|
+
*
|
2196
|
+
* (500).duration() -> '500 milliseconds'
|
2197
|
+
* (1200).duration() -> '1 second'
|
2198
|
+
* (75).minutes().duration() -> '1 hour'
|
2199
|
+
* (75).minutes().duration('es') -> '1 hora'
|
2200
|
+
*
|
2201
|
+
***/
|
2202
|
+
'duration': function(code) {
|
2203
|
+
return Date.getLocale(code).duration(this);
|
2204
|
+
}
|
2205
|
+
|
2206
|
+
});
|
2207
|
+
|
2208
|
+
buildDate();
|
2209
|
+
|
2210
|
+
})();
|