17
17
* limitations under the License.
18
18
*/
19
19
20
- import { int } from '../integer' ;
20
+ import { int , isInt } from '../integer' ;
21
21
import { Date , LocalDateTime , LocalTime } from '../temporal-types' ;
22
+ import { assertNumberOrInteger } from './util' ;
23
+ import { newError } from '../error' ;
22
24
23
25
/*
24
26
Code in this util should be compatible with code in the database that uses JSR-310 java.time APIs.
@@ -31,10 +33,41 @@ import {Date, LocalDateTime, LocalTime} from '../temporal-types';
31
33
conversion functions.
32
34
*/
33
35
36
+ class ValueRange {
37
+
38
+ constructor ( min , max ) {
39
+ this . _minNumber = min ;
40
+ this . _maxNumber = max ;
41
+ this . _minInteger = int ( min ) ;
42
+ this . _maxInteger = int ( max ) ;
43
+ }
44
+
45
+ contains ( value ) {
46
+ if ( isInt ( value ) ) {
47
+ return value . greaterThanOrEqual ( this . _minInteger ) && value . lessThanOrEqual ( this . _maxInteger ) ;
48
+ } else {
49
+ return value >= this . _minNumber && value <= this . _maxNumber ;
50
+ }
51
+ }
52
+
53
+ toString ( ) {
54
+ return `[${ this . _minNumber } , ${ this . _maxNumber } ]` ;
55
+ }
56
+ }
57
+
58
+ const YEAR_RANGE = new ValueRange ( - 999999999 , 999999999 ) ;
59
+ const MONTH_OF_YEAR_RANGE = new ValueRange ( 1 , 12 ) ;
60
+ const DAY_OF_MONTH_RANGE = new ValueRange ( 1 , 31 ) ;
61
+ const HOUR_OF_DAY_RANGE = new ValueRange ( 0 , 23 ) ;
62
+ const MINUTE_OF_HOUR_RANGE = new ValueRange ( 0 , 59 ) ;
63
+ const SECOND_OF_MINUTE_RANGE = new ValueRange ( 0 , 59 ) ;
64
+ const NANOSECOND_OF_SECOND_RANGE = new ValueRange ( 0 , 999999999 ) ;
65
+
34
66
const MINUTES_PER_HOUR = 60 ;
35
67
const SECONDS_PER_MINUTE = 60 ;
36
68
const SECONDS_PER_HOUR = SECONDS_PER_MINUTE * MINUTES_PER_HOUR ;
37
69
const NANOS_PER_SECOND = 1000000000 ;
70
+ const NANOS_PER_MILLISECOND = 1000000 ;
38
71
const NANOS_PER_MINUTE = NANOS_PER_SECOND * SECONDS_PER_MINUTE ;
39
72
const NANOS_PER_HOUR = NANOS_PER_MINUTE * MINUTES_PER_HOUR ;
40
73
const DAYS_0000_TO_1970 = 719528 ;
@@ -264,6 +297,105 @@ export function dateToIsoString(year, month, day) {
264
297
return `${ yearString } -${ monthString } -${ dayString } ` ;
265
298
}
266
299
300
+ /**
301
+ * Get the total number of nanoseconds from the milliseconds of the given standard JavaScript date and optional nanosecond part.
302
+ * @param {global.Date } standardDate the standard JavaScript date.
303
+ * @param {Integer|number|undefined } nanoseconds the optional number of nanoseconds.
304
+ * @return {Integer|number } the total amount of nanoseconds.
305
+ */
306
+ export function totalNanoseconds ( standardDate , nanoseconds ) {
307
+ nanoseconds = ( nanoseconds || 0 ) ;
308
+ const nanosFromMillis = standardDate . getMilliseconds ( ) * NANOS_PER_MILLISECOND ;
309
+ return isInt ( nanoseconds ) ? nanoseconds . add ( nanosFromMillis ) : nanoseconds + nanosFromMillis ;
310
+ }
311
+
312
+ /**
313
+ * Get the time zone offset in seconds from the given standard JavaScript date.
314
+ * @param {global.Date } standardDate the standard JavaScript date.
315
+ * @return {number } the time zone offset in seconds.
316
+ */
317
+ export function timeZoneOffsetInSeconds ( standardDate ) {
318
+ return standardDate . getTimezoneOffset ( ) * SECONDS_PER_MINUTE ;
319
+ }
320
+
321
+ /**
322
+ * Assert that the year value is valid.
323
+ * @param {Integer|number } year the value to check.
324
+ * @return {Integer|number } the value of the year if it is valid. Exception is thrown otherwise.
325
+ */
326
+ export function assertValidYear ( year ) {
327
+ return assertValidTemporalValue ( year , YEAR_RANGE , 'Year' ) ;
328
+ }
329
+
330
+ /**
331
+ * Assert that the month value is valid.
332
+ * @param {Integer|number } month the value to check.
333
+ * @return {Integer|number } the value of the month if it is valid. Exception is thrown otherwise.
334
+ */
335
+ export function assertValidMonth ( month ) {
336
+ return assertValidTemporalValue ( month , MONTH_OF_YEAR_RANGE , 'Month' ) ;
337
+ }
338
+
339
+ /**
340
+ * Assert that the day value is valid.
341
+ * @param {Integer|number } day the value to check.
342
+ * @return {Integer|number } the value of the day if it is valid. Exception is thrown otherwise.
343
+ */
344
+ export function assertValidDay ( day ) {
345
+ return assertValidTemporalValue ( day , DAY_OF_MONTH_RANGE , 'Day' ) ;
346
+ }
347
+
348
+ /**
349
+ * Assert that the hour value is valid.
350
+ * @param {Integer|number } hour the value to check.
351
+ * @return {Integer|number } the value of the hour if it is valid. Exception is thrown otherwise.
352
+ */
353
+ export function assertValidHour ( hour ) {
354
+ return assertValidTemporalValue ( hour , HOUR_OF_DAY_RANGE , 'Hour' ) ;
355
+ }
356
+
357
+ /**
358
+ * Assert that the minute value is valid.
359
+ * @param {Integer|number } minute the value to check.
360
+ * @return {Integer|number } the value of the minute if it is valid. Exception is thrown otherwise.
361
+ */
362
+ export function assertValidMinute ( minute ) {
363
+ return assertValidTemporalValue ( minute , MINUTE_OF_HOUR_RANGE , 'Minute' ) ;
364
+ }
365
+
366
+ /**
367
+ * Assert that the second value is valid.
368
+ * @param {Integer|number } second the value to check.
369
+ * @return {Integer|number } the value of the second if it is valid. Exception is thrown otherwise.
370
+ */
371
+ export function assertValidSecond ( second ) {
372
+ return assertValidTemporalValue ( second , SECOND_OF_MINUTE_RANGE , 'Second' ) ;
373
+ }
374
+
375
+ /**
376
+ * Assert that the nanosecond value is valid.
377
+ * @param {Integer|number } nanosecond the value to check.
378
+ * @return {Integer|number } the value of the nanosecond if it is valid. Exception is thrown otherwise.
379
+ */
380
+ export function assertValidNanosecond ( nanosecond ) {
381
+ return assertValidTemporalValue ( nanosecond , NANOSECOND_OF_SECOND_RANGE , 'Nanosecond' ) ;
382
+ }
383
+
384
+ /**
385
+ * Check if the given value is of expected type and is in the expected range.
386
+ * @param {Integer|number } value the value to check.
387
+ * @param {ValueRange } range the range.
388
+ * @param {string } name the name of the value.
389
+ * @return {Integer|number } the value if valid. Exception is thrown otherwise.
390
+ */
391
+ function assertValidTemporalValue ( value , range , name ) {
392
+ assertNumberOrInteger ( value , name ) ;
393
+ if ( ! range . contains ( value ) ) {
394
+ throw newError ( `${ name } is expected to be in range ${ range } but was: ${ value } ` ) ;
395
+ }
396
+ return value ;
397
+ }
398
+
267
399
/**
268
400
* Converts given local time into a single integer representing this same time in seconds of the day. Nanoseconds are skipped.
269
401
* @param {Integer|number|string } hour the hour of the local time.
0 commit comments