import assert from 'assert' ; import differenceInDays from '.' ; import { getDstTransitions } from '../../test/dst/tzOffsetTransitions' ; describe ( 'differenceInDays' , ( ) => { it ( 'returns the number of full days between the given dates' , ( ) => { const result = differenceInDays ( new Date ( 2012 , 6 , 2 , 18 , 0 ) , new Date ( 2011 , 6 , 2 , 6 , 0 ) ) ; assert ( result === 366 ) ; } ) ; it ( 'returns a negative number if the time value of the first date is smaller' , ( ) => { const result = differenceInDays ( new Date ( 2011 , 6 , 2 , 6 , 0 ) , new Date ( 2012 , 6 , 2 , 18 , 0 ) ) ; assert ( result === - 366 ) ; } ) ; it ( 'accepts timestamps' , ( ) => { const result = differenceInDays ( new Date ( 2014 , 8 , 5 , 18 , 0 ) . getTime ( ) , new Date ( 2014 , 8 , 4 , 6 , 0 ) . getTime ( ) ) ; assert ( result === 1 ) ; } ) ; describe ( 'edge cases' , ( ) => { it ( 'the difference is less than a day, but the given dates are in different calendar days' , ( ) => { const result = differenceInDays ( new Date ( 2014 , 8 , 5 , 0 , 0 ) , new Date ( 2014 , 8 , 4 , 23 , 59 ) ) ; assert ( result === 0 ) ; } ) ; it ( 'the same for the swapped dates' , ( ) => { const result = differenceInDays ( new Date ( 2014 , 8 , 4 , 23 , 59 ) , new Date ( 2014 , 8 , 5 , 0 , 0 ) ) ; assert ( result === 0 ) ; } ) ; it ( 'the time values of the given dates are the same' , ( ) => { const result = differenceInDays ( new Date ( 2014 , 8 , 6 , 0 , 0 ) , new Date ( 2014 , 8 , 5 , 0 , 0 ) ) ; assert ( result === 1 ) ; } ) ; it ( 'the given dates are the same' , ( ) => { const result = differenceInDays ( new Date ( 2014 , 8 , 5 , 0 , 0 ) , new Date ( 2014 , 8 , 5 , 0 , 0 ) ) ; assert ( result === 0 ) ; } ) ; const dstTransitions = getDstTransitions ( 2017 ) ; const dstOnly = dstTransitions . start && dstTransitions . end ? it : it . skip ; const tz = Intl . DateTimeFormat ( ) . resolvedOptions ( ) . timeZone || process . env . tz ; dstOnly ( `works across DST start & end in local timezone: ${ tz || '(unknown)' }` , ( ) => { const { start , end } = dstTransitions ; const HOUR = 1000 * 60 * 60 ; const MINUTE = 1000 * 60 ; function sameTime ( t1 , t2 ) { return ( t1 . getHours ( ) === t2 . getHours ( ) && t1 . getMinutes ( ) === t2 . getMinutes ( ) && t1 . getSeconds ( ) === t2 . getSeconds ( ) && t1 . getMilliseconds ( ) === t2 . getMilliseconds ( ) ) ; } assert ( start !== undefined ) ; assert ( end !== undefined ) ; if ( start === undefined || end === undefined ) { return ; } const dstOffset = ( end . getTimezoneOffset ( ) - start . getTimezoneOffset ( ) ) * MINUTE ; { const a = new Date ( start . getTime ( ) - HOUR ) ; const b = new Date ( a . getTime ( ) + 24 * HOUR - dstOffset ) ; const c = new Date ( a . getTime ( ) + 48 * HOUR - dstOffset ) ; assert ( sameTime ( a , b ) ) ; assert ( sameTime ( a , c ) ) ; assert ( sameTime ( b , c ) ) ; assert ( differenceInDays ( c , b ) === 1 ) ; assert ( differenceInDays ( b , a ) === 1 ) ; assert ( differenceInDays ( c , a ) === 2 ) ; } { const a = start ; const b = new Date ( a . getTime ( ) + 24 * HOUR ) ; const c = new Date ( a . getTime ( ) + 48 * HOUR ) ; assert ( sameTime ( a , b ) ) ; assert ( sameTime ( a , c ) ) ; assert ( sameTime ( b , c ) ) ; assert ( differenceInDays ( c , b ) === 1 ) ; assert ( differenceInDays ( b , a ) === 1 ) ; assert ( differenceInDays ( c , a ) === 2 ) ; } { const a = new Date ( end . getTime ( ) - HOUR / 2 ) ; const b = new Date ( a . getTime ( ) + 24 * HOUR + dstOffset - 15 * MINUTE ) ; const c = new Date ( a . getTime ( ) + 48 * HOUR + dstOffset - 15 * MINUTE ) ; assert ( differenceInDays ( c , b ) === 1 ) ; assert ( differenceInDays ( b , a ) === 0 ) ; assert ( differenceInDays ( c , a ) === 1 ) ; } { const a = new Date ( end . getTime ( ) - HOUR ) ; const b = new Date ( a . getTime ( ) + 24 * HOUR + dstOffset ) ; const c = new Date ( a . getTime ( ) + 48 * HOUR + dstOffset ) ; assert ( sameTime ( a , b ) ) ; assert ( sameTime ( a , c ) ) ; assert ( sameTime ( b , c ) ) ; assert ( differenceInDays ( c , b ) === 1 ) ; assert ( differenceInDays ( b , a ) === 1 ) ; assert ( differenceInDays ( c , a ) === 2 ) ; } { const a = new Date ( end . getTime ( ) + HOUR ) ; const b = new Date ( a . getTime ( ) + 24 * HOUR ) ; const c = new Date ( a . getTime ( ) + 48 * HOUR ) ; assert ( sameTime ( a , b ) ) ; assert ( sameTime ( a , c ) ) ; assert ( sameTime ( b , c ) ) ; assert ( differenceInDays ( c , b ) === 1 ) ; assert ( differenceInDays ( b , a ) === 1 ) ; assert ( differenceInDays ( c , a ) === 2 ) ; } { const a = end ; const b = new Date ( a . getTime ( ) + 24 * HOUR ) ; const c = new Date ( a . getTime ( ) + 48 * HOUR ) ; assert ( differenceInDays ( b , a ) === 1 ) ; assert ( differenceInDays ( c , a ) === 2 ) ; } } ) ; it ( 'does not return -0 when the given dates are the same' , ( ) => { function isNegativeZero ( x ) { return x === 0 && 1 / x < 0 ; } const result = differenceInDays ( new Date ( 2014 , 8 , 5 , 0 , 0 ) , new Date ( 2014 , 8 , 5 , 0 , 0 ) ) ; const resultIsNegative = isNegativeZero ( result ) ; assert ( resultIsNegative === false ) ; } ) ; } ) ; it ( 'returns NaN if the first date is `Invalid Date`' , ( ) => { const result = differenceInDays ( new Date ( NaN ) , new Date ( 2017 , 0 , 1 ) ) ; assert ( isNaN ( result ) ) ; } ) ; it ( 'returns NaN if the second date is `Invalid Date`' , ( ) => { const result = differenceInDays ( new Date ( 2017 , 0 , 1 ) , new Date ( NaN ) ) ; assert ( isNaN ( result ) ) ; } ) ; it ( 'returns NaN if the both dates are `Invalid Date`' , ( ) => { const result = differenceInDays ( new Date ( NaN ) , new Date ( NaN ) ) ; assert ( isNaN ( result ) ) ; } ) ; it ( 'throws TypeError exception if passed less than 2 arguments' , ( ) => { assert . throws ( differenceInDays . bind ( null ) , TypeError ) ; assert . throws ( differenceInDays . bind ( null , 1 ) , TypeError ) ; } ) ; } ) ;