[GAS][JS] Moment 라이브러리의 diff에서 날짜 차이
(추기 2020/09/19) Moment.js의 개발이 종료한 것 같습니다.
↓ 여기 참조
htps : // 모멘 tjs. 이 m/두 cs/
지금 라이브러리를 사용할 수 없게 되는 것은 없다고 생각합니다만, 앞으로, 적극적으로 이 라이브러리를 선택할지 어떨지는 생각이군요.
그리고 GAS 버전의 라이브러리가 어떻게 될지에 대한 정보를 찾을 수 없습니다. (누군가를 알고 싶으면)
GAS로 이야기하지만 Javascript에서도 마찬가지입니다.
GAS 버전 Moment 라이브러리의 ID는 아래와 같습니다.
MHMchiX6c1bwSqGM1PZiW_PxhMjh3Sh48
하고 싶었던 일
이런 표를 만들고, 매일 아침 8시대에 GAS가 기동해, 「마감까지 3일」이내가 되면 「마감 가깝지만 괜찮아?」라고 하는 리마인드를 해 주는 기능을 만들고 싶다.
그 때문에 Moment 라이브러리를 사용해 「날짜의 차분」을 취하고 싶었다.
좋지 않은 예
단순화를 위해 A2 셀의 날짜만을 대상으로 합니다.
처음에는 이렇게 썼습니다.
function sample1() {
// 日付のセルからgetValue()したら Dateオブジェクト が取れるのでこう書いてしまいます
const deadline_date = new Date("2020-09-10");
const deadline_moment = Moment.moment(deadline_date);
const now_moment = Moment.moment();
const diff = deadline_moment.diff(now_moment, "days");
console.log(diff);
}
그리고 「오늘은 2020/9/9라고 한다」가 아닙니까.
A2셀은 2020/9/10이므로 1이 출력될 것을 기대하지 않습니까?
그러나 출력 결과는 "0"
좋지 않은 이유
상기에서 「오늘은 2020/9/9라고 한다」라고 썼습니다만,
실제로 이 GAS가 실행되는 시간은 2020/09/09 12:34:56이거나 하는 것입니다.
그리고 deadline 으로 지정하고 있는 것은 「2020-09-10 00:00:00」입니다.
실험해 보면 이렇게 되었습니다 ↓
function sample2() {
const deadline_date = new Date("2020-09-10 00:00:00");
const deadline_moment = Moment.moment(deadline_date);
const now_moment1 = Moment.moment("2020-09-09 00:00:00");
const diff1 = deadline_moment.diff(now_moment1, "days");
console.log(diff1); //=> 1
const now_moment2 = Moment.moment("2020-09-09 00:00:01");
const diff2 = deadline_moment.diff(now_moment2, "days");
console.log(diff2); //=> 0
}
now_moment1과 now_moment2는 "1 초"다릅니다.
diff1 에서는 deadline인 2020-09-10 00:00:00 과 2020-09-09 00:00:00 의 차이가 24:00:00 이므로 하루.
diff2 에서는 deadline인 2020-09-10 00:00:00 과 2020-09-09 00:00:01 의 차이가 23:59:59 이므로 0일.
라는 움직임 같다.
어떻게 해야할까
「날짜」로 비교하고 싶기 때문에 이런 것이라고 하는 것은.
「시분초 밀리 세컨드에 제로를 세트 버린다」작전
function sample3() {
const deadline_date = new Date("2020-09-10 00:00:00");
const deadline_moment = Moment.moment(deadline_date);
// 時分秒ミリ秒にゼロをセットしちゃう
const today_moment = Moment.moment().hour(0).minutes(0).second(0).millisecond(0);
const diff = deadline_moment.diff(today_moment, "days");
console.log(diff);
}
이제 실행 시간이 "2020-09-09 11:11:11"이더라도 "1"이 출력됩니다.
↓ 만약을 위해 실험
function sample4() {
const deadline_date = new Date("2020-09-10 00:00:00");
const deadline_moment = Moment.moment(deadline_date);
const now = new Date("2020-09-09 11:11:11")
const today_moment = Moment.moment(now).hour(0).minutes(0).second(0).millisecond(0);
const diff = deadline_moment.diff(today_moment, "days");
console.log(diff); //=> 1
}
예상대로!
정말 그렇죠?
"days"로 비교할 때, "24시간 미만인지 아닌지로 판정하고 있다"는 것은, 동작시킨 결과를 보고 내가 추측하고 있는 곳입니다만, 실제로 어떤 구현이 되어 있는지 moment 라이브러리 diff.js 소스 코드 를 보았습니다. (이것은 moment.js의 소스 코드이며 GAS 라이브러리의 코드가 아니기 때문에 GAS에서는 다른 구현 일 수 있지만 분명히 동일합니다)
export function diff(input, units, asFloat) {
var that, zoneDelta, output;
if (!this.isValid()) {
return NaN;
}
that = cloneWithOffset(input, this);
if (!that.isValid()) {
return NaN;
}
zoneDelta = (that.utcOffset() - this.utcOffset()) * 6e4;
units = normalizeUnits(units);
switch (units) {
// 略
case 'day':
output = (this - that - zoneDelta) / 864e5;
break; // 1000 * 60 * 60 * 24, negate dst
// 略
}
return asFloat ? output : absFloor(output);
}
864e5
는 1 일을 밀리 세컨드로 했을 때의 86400000 의 지수 표기.
따라서 시간의 차이를 하루를 나타내는 밀리 세컨드로 나눕니다.
diff 함수의 세 번째 인수 asFloat
는 지정하지 않으므로,
return asFloat ? output : absFloor(output);
그럼 absFloor(output)
가 return 된다.
absFloor()
함수의 정의는 여기
export default function absFloor(number) {
if (number < 0) {
// -0 -> 0
return Math.ceil(number) || 0;
} else {
return Math.floor(number);
}
}
Math.ceil() : 인수로 주어진 숫자 이상의 최소 정수를 반환합니다.
Math.floor() : 인수로 주어진 숫자 이하의 최대 정수를 반환합니다.
그래서 output (시간의 차이를 하루를 나타내는 밀리 초로 나눈 숫자)
MHMchiX6c1bwSqGM1PZiW_PxhMjh3Sh48
이런 표를 만들고, 매일 아침 8시대에 GAS가 기동해, 「마감까지 3일」이내가 되면 「마감 가깝지만 괜찮아?」라고 하는 리마인드를 해 주는 기능을 만들고 싶다.
그 때문에 Moment 라이브러리를 사용해 「날짜의 차분」을 취하고 싶었다.
좋지 않은 예
단순화를 위해 A2 셀의 날짜만을 대상으로 합니다.
처음에는 이렇게 썼습니다.
function sample1() {
// 日付のセルからgetValue()したら Dateオブジェクト が取れるのでこう書いてしまいます
const deadline_date = new Date("2020-09-10");
const deadline_moment = Moment.moment(deadline_date);
const now_moment = Moment.moment();
const diff = deadline_moment.diff(now_moment, "days");
console.log(diff);
}
그리고 「오늘은 2020/9/9라고 한다」가 아닙니까.
A2셀은 2020/9/10이므로 1이 출력될 것을 기대하지 않습니까?
그러나 출력 결과는 "0"
좋지 않은 이유
상기에서 「오늘은 2020/9/9라고 한다」라고 썼습니다만,
실제로 이 GAS가 실행되는 시간은 2020/09/09 12:34:56이거나 하는 것입니다.
그리고 deadline 으로 지정하고 있는 것은 「2020-09-10 00:00:00」입니다.
실험해 보면 이렇게 되었습니다 ↓
function sample2() {
const deadline_date = new Date("2020-09-10 00:00:00");
const deadline_moment = Moment.moment(deadline_date);
const now_moment1 = Moment.moment("2020-09-09 00:00:00");
const diff1 = deadline_moment.diff(now_moment1, "days");
console.log(diff1); //=> 1
const now_moment2 = Moment.moment("2020-09-09 00:00:01");
const diff2 = deadline_moment.diff(now_moment2, "days");
console.log(diff2); //=> 0
}
now_moment1과 now_moment2는 "1 초"다릅니다.
diff1 에서는 deadline인 2020-09-10 00:00:00 과 2020-09-09 00:00:00 의 차이가 24:00:00 이므로 하루.
diff2 에서는 deadline인 2020-09-10 00:00:00 과 2020-09-09 00:00:01 의 차이가 23:59:59 이므로 0일.
라는 움직임 같다.
어떻게 해야할까
「날짜」로 비교하고 싶기 때문에 이런 것이라고 하는 것은.
「시분초 밀리 세컨드에 제로를 세트 버린다」작전
function sample3() {
const deadline_date = new Date("2020-09-10 00:00:00");
const deadline_moment = Moment.moment(deadline_date);
// 時分秒ミリ秒にゼロをセットしちゃう
const today_moment = Moment.moment().hour(0).minutes(0).second(0).millisecond(0);
const diff = deadline_moment.diff(today_moment, "days");
console.log(diff);
}
이제 실행 시간이 "2020-09-09 11:11:11"이더라도 "1"이 출력됩니다.
↓ 만약을 위해 실험
function sample4() {
const deadline_date = new Date("2020-09-10 00:00:00");
const deadline_moment = Moment.moment(deadline_date);
const now = new Date("2020-09-09 11:11:11")
const today_moment = Moment.moment(now).hour(0).minutes(0).second(0).millisecond(0);
const diff = deadline_moment.diff(today_moment, "days");
console.log(diff); //=> 1
}
예상대로!
정말 그렇죠?
"days"로 비교할 때, "24시간 미만인지 아닌지로 판정하고 있다"는 것은, 동작시킨 결과를 보고 내가 추측하고 있는 곳입니다만, 실제로 어떤 구현이 되어 있는지 moment 라이브러리 diff.js 소스 코드 를 보았습니다. (이것은 moment.js의 소스 코드이며 GAS 라이브러리의 코드가 아니기 때문에 GAS에서는 다른 구현 일 수 있지만 분명히 동일합니다)
export function diff(input, units, asFloat) {
var that, zoneDelta, output;
if (!this.isValid()) {
return NaN;
}
that = cloneWithOffset(input, this);
if (!that.isValid()) {
return NaN;
}
zoneDelta = (that.utcOffset() - this.utcOffset()) * 6e4;
units = normalizeUnits(units);
switch (units) {
// 略
case 'day':
output = (this - that - zoneDelta) / 864e5;
break; // 1000 * 60 * 60 * 24, negate dst
// 略
}
return asFloat ? output : absFloor(output);
}
864e5
는 1 일을 밀리 세컨드로 했을 때의 86400000 의 지수 표기.
따라서 시간의 차이를 하루를 나타내는 밀리 세컨드로 나눕니다.
diff 함수의 세 번째 인수 asFloat
는 지정하지 않으므로,
return asFloat ? output : absFloor(output);
그럼 absFloor(output)
가 return 된다.
absFloor()
함수의 정의는 여기
export default function absFloor(number) {
if (number < 0) {
// -0 -> 0
return Math.ceil(number) || 0;
} else {
return Math.floor(number);
}
}
Math.ceil() : 인수로 주어진 숫자 이상의 최소 정수를 반환합니다.
Math.floor() : 인수로 주어진 숫자 이하의 최대 정수를 반환합니다.
그래서 output (시간의 차이를 하루를 나타내는 밀리 초로 나눈 숫자)
function sample1() {
// 日付のセルからgetValue()したら Dateオブジェクト が取れるのでこう書いてしまいます
const deadline_date = new Date("2020-09-10");
const deadline_moment = Moment.moment(deadline_date);
const now_moment = Moment.moment();
const diff = deadline_moment.diff(now_moment, "days");
console.log(diff);
}
상기에서 「오늘은 2020/9/9라고 한다」라고 썼습니다만,
실제로 이 GAS가 실행되는 시간은 2020/09/09 12:34:56이거나 하는 것입니다.
그리고 deadline 으로 지정하고 있는 것은 「2020-09-10 00:00:00」입니다.
실험해 보면 이렇게 되었습니다 ↓
function sample2() {
const deadline_date = new Date("2020-09-10 00:00:00");
const deadline_moment = Moment.moment(deadline_date);
const now_moment1 = Moment.moment("2020-09-09 00:00:00");
const diff1 = deadline_moment.diff(now_moment1, "days");
console.log(diff1); //=> 1
const now_moment2 = Moment.moment("2020-09-09 00:00:01");
const diff2 = deadline_moment.diff(now_moment2, "days");
console.log(diff2); //=> 0
}
now_moment1과 now_moment2는 "1 초"다릅니다.
diff1 에서는 deadline인 2020-09-10 00:00:00 과 2020-09-09 00:00:00 의 차이가 24:00:00 이므로 하루.
diff2 에서는 deadline인 2020-09-10 00:00:00 과 2020-09-09 00:00:01 의 차이가 23:59:59 이므로 0일.
라는 움직임 같다.
어떻게 해야할까
「날짜」로 비교하고 싶기 때문에 이런 것이라고 하는 것은.
「시분초 밀리 세컨드에 제로를 세트 버린다」작전
function sample3() {
const deadline_date = new Date("2020-09-10 00:00:00");
const deadline_moment = Moment.moment(deadline_date);
// 時分秒ミリ秒にゼロをセットしちゃう
const today_moment = Moment.moment().hour(0).minutes(0).second(0).millisecond(0);
const diff = deadline_moment.diff(today_moment, "days");
console.log(diff);
}
이제 실행 시간이 "2020-09-09 11:11:11"이더라도 "1"이 출력됩니다.
↓ 만약을 위해 실험
function sample4() {
const deadline_date = new Date("2020-09-10 00:00:00");
const deadline_moment = Moment.moment(deadline_date);
const now = new Date("2020-09-09 11:11:11")
const today_moment = Moment.moment(now).hour(0).minutes(0).second(0).millisecond(0);
const diff = deadline_moment.diff(today_moment, "days");
console.log(diff); //=> 1
}
예상대로!
정말 그렇죠?
"days"로 비교할 때, "24시간 미만인지 아닌지로 판정하고 있다"는 것은, 동작시킨 결과를 보고 내가 추측하고 있는 곳입니다만, 실제로 어떤 구현이 되어 있는지 moment 라이브러리 diff.js 소스 코드 를 보았습니다. (이것은 moment.js의 소스 코드이며 GAS 라이브러리의 코드가 아니기 때문에 GAS에서는 다른 구현 일 수 있지만 분명히 동일합니다)
export function diff(input, units, asFloat) {
var that, zoneDelta, output;
if (!this.isValid()) {
return NaN;
}
that = cloneWithOffset(input, this);
if (!that.isValid()) {
return NaN;
}
zoneDelta = (that.utcOffset() - this.utcOffset()) * 6e4;
units = normalizeUnits(units);
switch (units) {
// 略
case 'day':
output = (this - that - zoneDelta) / 864e5;
break; // 1000 * 60 * 60 * 24, negate dst
// 略
}
return asFloat ? output : absFloor(output);
}
864e5
는 1 일을 밀리 세컨드로 했을 때의 86400000 의 지수 표기.
따라서 시간의 차이를 하루를 나타내는 밀리 세컨드로 나눕니다.
diff 함수의 세 번째 인수 asFloat
는 지정하지 않으므로,
return asFloat ? output : absFloor(output);
그럼 absFloor(output)
가 return 된다.
absFloor()
함수의 정의는 여기
export default function absFloor(number) {
if (number < 0) {
// -0 -> 0
return Math.ceil(number) || 0;
} else {
return Math.floor(number);
}
}
Math.ceil() : 인수로 주어진 숫자 이상의 최소 정수를 반환합니다.
Math.floor() : 인수로 주어진 숫자 이하의 최대 정수를 반환합니다.
그래서 output (시간의 차이를 하루를 나타내는 밀리 초로 나눈 숫자)
function sample3() {
const deadline_date = new Date("2020-09-10 00:00:00");
const deadline_moment = Moment.moment(deadline_date);
// 時分秒ミリ秒にゼロをセットしちゃう
const today_moment = Moment.moment().hour(0).minutes(0).second(0).millisecond(0);
const diff = deadline_moment.diff(today_moment, "days");
console.log(diff);
}
function sample4() {
const deadline_date = new Date("2020-09-10 00:00:00");
const deadline_moment = Moment.moment(deadline_date);
const now = new Date("2020-09-09 11:11:11")
const today_moment = Moment.moment(now).hour(0).minutes(0).second(0).millisecond(0);
const diff = deadline_moment.diff(today_moment, "days");
console.log(diff); //=> 1
}
"days"로 비교할 때, "24시간 미만인지 아닌지로 판정하고 있다"는 것은, 동작시킨 결과를 보고 내가 추측하고 있는 곳입니다만, 실제로 어떤 구현이 되어 있는지 moment 라이브러리 diff.js 소스 코드 를 보았습니다. (이것은 moment.js의 소스 코드이며 GAS 라이브러리의 코드가 아니기 때문에 GAS에서는 다른 구현 일 수 있지만 분명히 동일합니다)
export function diff(input, units, asFloat) {
var that, zoneDelta, output;
if (!this.isValid()) {
return NaN;
}
that = cloneWithOffset(input, this);
if (!that.isValid()) {
return NaN;
}
zoneDelta = (that.utcOffset() - this.utcOffset()) * 6e4;
units = normalizeUnits(units);
switch (units) {
// 略
case 'day':
output = (this - that - zoneDelta) / 864e5;
break; // 1000 * 60 * 60 * 24, negate dst
// 略
}
return asFloat ? output : absFloor(output);
}
864e5
는 1 일을 밀리 세컨드로 했을 때의 86400000 의 지수 표기.따라서 시간의 차이를 하루를 나타내는 밀리 세컨드로 나눕니다.
diff 함수의 세 번째 인수
asFloat
는 지정하지 않으므로,return asFloat ? output : absFloor(output);
그럼
absFloor(output)
가 return 된다.absFloor()
함수의 정의는 여기export default function absFloor(number) {
if (number < 0) {
// -0 -> 0
return Math.ceil(number) || 0;
} else {
return Math.floor(number);
}
}
Math.ceil() : 인수로 주어진 숫자 이상의 최소 정수를 반환합니다.
Math.floor() : 인수로 주어진 숫자 이하의 최대 정수를 반환합니다.
그래서 output (시간의 차이를 하루를 나타내는 밀리 초로 나눈 숫자)
내 추측은 있었던 것 같습니다! (...라는 여기까지의 흐름이 잘못되면 가르쳐 주었으면 합니다)
결론
그렇다고 해서 「날」을 비교하고 싶다면, 「날」(date)보다 작은 단위(hour, minutes, second, millisecond)는 제로로 메워 준다
보충이지만 밀리 초가 나오면
const deadline_date = new Date("2020-09-10 00:00:00.000");
하는 편이 입도는 갖추어지네요.
(밀리 세컨드까지 지정해 Date 객체를 new 한 적이 없기 때문에 힘들다)
Reference
이 문제에 관하여([GAS][JS] Moment 라이브러리의 diff에서 날짜 차이), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/sakaimo/items/b79bff16f85613130556
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
const deadline_date = new Date("2020-09-10 00:00:00.000");
Reference
이 문제에 관하여([GAS][JS] Moment 라이브러리의 diff에서 날짜 차이), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/sakaimo/items/b79bff16f85613130556텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)