development

문자열 표현을 사용하지 않고 설정된 시간대로 날짜 만들기

big-blog 2020. 2. 23. 11:57
반응형

문자열 표현을 사용하지 않고 설정된 시간대로 날짜 만들기


일, 월 및 연도에 대한 3 개의 드롭 다운이있는 웹 페이지가 있습니다. Date숫자를 취하는 JavaScript 생성자를 사용하면 Date현재 시간대에 대한 객체를 얻습니다 .

new Date(xiYear, xiMonth, xiDate)

정확한 날짜를 제공하되 일광 절약 시간제 때문에 날짜가 GMT + 01 : 00 인 것으로 생각합니다.

여기서 문제는 이것을 DateAjax 메소드에 전달 하고 서버에서 날짜가 직렬화 해제되면 GMT로 변환되어 하루가 한 시간 뒤로 이동하는 시간이 없어진다는 것입니다. 이제 일, 월, 년을 개별적으로 Ajax 방법으로 전달할 수는 있지만 더 나은 방법이 있어야합니다.

받아 들여진 대답은 올바른 방향으로 나를 지적했지만, setUTCHours()그 자체 만 사용하면 변경되었습니다.

Apr 5th 00:00 GMT+01:00 

Apr 4th 23:00 GMT+01:00

그런 다음 UTC 날짜, 월 및 연도를 설정해야했습니다.

Apr 5th 01:00 GMT+01:00

내가 원하는 것입니다.


사용 .setUTCHours()이하면 시스템 전체 UTC-시간을 사용할 수 있도록 할 UTC 타임 실제로 설정 날짜, 할 수있을 것입니다.

날짜 문자열을 지정하지 않으면 생성자에서 UTC를 사용하여 설정할 수 없습니다.

를 사용 new Date(Date.UTC(year, month, day, hour, minute, second))하면 특정 UTC 시간에서 Date 객체를 만들 수 있습니다.


var d = new Date(xiYear, xiMonth, xiDate);
d.setTime( d.getTime() + d.getTimezoneOffset()*60*1000 );

이 답변은 원래 질문에 특별히 맞춰져 있으며 반드시 필요한 답변을 제공하지는 않습니다. 특히 일부 사람들은 시간대 오프셋을 더하는 대신 빼기를 원할 것입니다. 이 솔루션의 요점은 특정 deserialization을 위해 javascript의 날짜 객체를 해킹하는 것이지만 모든 경우에 정확하지는 않습니다.


createDateAsUTC 함수 가 필요하다고 생각합니다 ( convertDateToUTC 와 비교 하십시오 )

function createDateAsUTC(date) {
    return new Date(Date.UTC(date.getFullYear(), date.getMonth(), date.getDate(), date.getHours(), date.getMinutes(), date.getSeconds()));
}

function convertDateToUTC(date) { 
    return new Date(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate(), date.getUTCHours(), date.getUTCMinutes(), date.getUTCSeconds()); 
}

시간대를 설정하고 다시 확인하기 만하면됩니다.

new Date().toLocaleString("en-US", {timeZone: "America/New_York"})

이것이 가능하지 않다고 생각합니다-Date 객체를 만든 후 시간대를 설정할 수는 없습니다.

그리고 이것은 개념적으로 (어쩌면 구현되지 않은 경우) 의미가 있습니다. http://en.wikipedia.org/wiki/Unix_timestamp (강조 광산) :

유닉스 시간 또는 POSIX 시간은 1970 년 1 월 1 일 목요일 자정 협정 세계시 (UTC) 이후 경과 된 시간 ( 초)으로 정의 된 시간을 설명하는 시스템입니다 .

하나를 구성하면 "실시간"의 특정 지점을 나타냅니다. 시간대는 해당 추상 시점을 사람이 읽을 수있는 문자열로 변환하려는 경우에만 관련이 있습니다.

따라서 Date가 생성자에서 나타내는 실제 시간 만 변경할 수 있다는 것이 합리적입니다. 안타깝게도 명시적인 시간대를 전달할 수있는 방법이없는 것 같습니다. 호출하는 생성자 (정확하게는 올바른)가 "현지"시간 변수를 표준 시간대로 저장할 때 GMT로 변환하므로 int, int, int생성자 를 사용할 수있는 방법이 없습니다. GMT 시간.

플러스 측면에서, 대신 String을 취하는 생성자를 사용하는 것은 쉽지 않습니다. 숫자 달을 문자열 (최소한 Firefox에서는)로 변환 할 필요조차 없으므로 순진한 구현이 작동하기를 바랐습니다. 그러나 그것을 시도한 후에는 Firefox, Chrome 및 Opera에서 성공적으로 작동하지만 Konqueror ( "Invalid Date"), Safari ( "Invalid Date") 및 IE ( "NaN")에서는 실패합니다. 월을 문자열로 변환하는 조회 배열이 있다고 가정합니다.

var months = [ '', 'January', 'February', ..., 'December'];

function createGMTDate(xiYear, xiMonth, xiDate) {
   return new Date(months[xiMonth] + ' ' + xiDate + ', ' + xiYear + ' 00:00:00 GMT');
}

나는 이것이 오래되었다는 것을 알고 있지만 그것이 도움이된다면 순간과 시간대를 사용할 수 있습니다. 당신이 그들을 보지 못했다면 살펴보십시오.

http://momentjs.com/timezone/

http://momentjs.com/

두 가지 편리한 시간 조작 라이브러리.


시간대를 포함하여 연도, 월, 일 등에서 Javascript Date 객체를 생성하는 약간 다르지만 관련이있는 문제 ( 즉, 문자열을 Date로 구문 분석하려는 경우)를 처리하려는 경우 명백하게 복잡한 춤을 추어 야한다 :

// parseISO8601String : string -> Date
// Parse an ISO-8601 date, including possible timezone,
// into a Javascript Date object.
//
// Test strings: parseISO8601String(x).toISOString()
// "2013-01-31T12:34"              -> "2013-01-31T12:34:00.000Z"
// "2013-01-31T12:34:56"           -> "2013-01-31T12:34:56.000Z"
// "2013-01-31T12:34:56.78"        -> "2013-01-31T12:34:56.780Z"
// "2013-01-31T12:34:56.78+0100"   -> "2013-01-31T11:34:56.780Z"
// "2013-01-31T12:34:56.78+0530"   -> "2013-01-31T07:04:56.780Z"
// "2013-01-31T12:34:56.78-0330"   -> "2013-01-31T16:04:56.780Z"
// "2013-01-31T12:34:56-0330"      -> "2013-01-31T16:04:56.000Z"
// "2013-01-31T12:34:56Z"          -> "2013-01-31T12:34:56.000Z"
function parseISO8601String(dateString) {
    var timebits = /^([0-9]{4})-([0-9]{2})-([0-9]{2})T([0-9]{2}):([0-9]{2})(?::([0-9]*)(\.[0-9]*)?)?(?:([+-])([0-9]{2})([0-9]{2}))?/;
    var m = timebits.exec(dateString);
    var resultDate;
    if (m) {
        var utcdate = Date.UTC(parseInt(m[1]),
                               parseInt(m[2])-1, // months are zero-offset (!)
                               parseInt(m[3]),
                               parseInt(m[4]), parseInt(m[5]), // hh:mm
                               (m[6] && parseInt(m[6]) || 0),  // optional seconds
                               (m[7] && parseFloat(m[7])*1000) || 0); // optional fraction
        // utcdate is milliseconds since the epoch
        if (m[9] && m[10]) {
            var offsetMinutes = parseInt(m[9]) * 60 + parseInt(m[10]);
            utcdate += (m[8] === '+' ? -1 : +1) * offsetMinutes * 60000;
        }
        resultDate = new Date(utcdate);
    } else {
        resultDate = null;
    }
    return resultDate;
}

즉, 시간대가없는 날짜를 사용하여 'UTC 시간'을 생성하므로 UTC가있는 로케일을 알 수 있습니다 (예 : UTC '로케일'및 로컬로 기본 설정되지 않음) 표시된 시간대 오프셋을 수동으로 적용하십시오.

누군가가 실제로 자바 스크립트 날짜 객체에 대해 5 분 이상 생각 했다면 좋지 않을 것입니다 ....


d = new Date();
utc = d.getTime() + (d.getTimezoneOffset() * 60000);
nd = new Date(utc + (3600000*offset));

offset value base on which location time zone you would like to set 
For India offset value +5.5,
New York offset value -4,
London offset value +1

모든 위치 오프셋 Wiki UTC 시간 오프셋 목록


getTimeZoneOffset은 UTC + z에 대한 빼기입니다.

var d = new Date(xiYear, xiMonth, xiDate);
if(d.getTimezoneOffset() > 0){
    d.setTime( d.getTime() + d.getTimezoneOffset()*60*1000 );
}

이것은 누군가에게 도움이 될 수 있습니다. 새로운 생성자에 전달한 내용의 끝에 UTC를 넣으십시오.

적어도 크롬에서는 말할 수 있습니다. var date = new Date("2014-01-01 11:00:00 UTC")


한 줄 솔루션

new Date(new Date(1422524805305).getTime() - 330*60*1000)

1422524805305 대신 밀리 초 단위의 타임 스탬프를 사용하십시오. 330 대신에 시간대 오프셋 (분)을 사용하십시오. GMT (예 : 인도 +5 : 30은 5 * 60 + 30 = 330 분)


// My clock 2018-07-25, 00:26:00 (GMT+7)
let date = new Date(); // 2018-07-24:17:26:00 (Look like GMT+0)
const myTimeZone = 7; // my timeZone 
// my timeZone = 7h = 7 * 60 * 60 * 1000 (millisecond);
// 2018-07-24:17:26:00 = x (milliseconds)
// finally, time in milliseconds (GMT+7) = x + myTimezone 
date.setTime( date.getTime() + myTimeZone * 60 * 60 * 1000 );
// date.toISOString() = 2018-07-25, 00:26:00 (GMT+7)

올바른 날짜를 얻는 가장 쉬운 방법은 datejs를 사용하는 것입니다.

http://www.datejs.com/

이 형식으로 Ajax를 통해 날짜를 문자열로 표시합니다. '2016-01-12T00 : 00 : 00'

var yourDateString = '2016-01-12T00:00:00';
var yourDate = new Date(yourDateString);
console.log(yourDate);
if (yourDate.getTimezoneOffset() > 0){
    yourDate = new Date(yourDateString).addMinutes(yourDate.getTimezoneOffset());
}
console.log(yourDate);

콘솔은 다음을 읽습니다 :

2016 년 1 월 11 일 월요일 19:00:00 GMT-0500 (동부 표준시)

화 1 월 12 일 2016 00:00:00 GMT-0500 (동부 표준시)

https://jsfiddle.net/vp1ena7b/3/

'addMinutes'는 datejs에서 온 것입니다. 아마도 순수 js에서 직접 할 수는 있지만 이미 프로젝트에 datejs가 있으므로 올바른 날짜를 얻는 데 사용할 수있는 방법을 찾았습니다.

나는 이것이 누군가를 도울 것이라고 생각했다 ...


어떤 마일리지

var d = new Date(xiYear, xiMonth, xiDate).toLocaleString();

내가 본 최고의 솔루션은

http://www.codingforums.com/archive/index.php/t-19663.html

인쇄 시간 기능

<script language="javascript" type="text/javascript">
//borrowed from echoecho
//http://www.echoecho.com/ubb/viewthread.php?tid=2362&pid=10482&#pid10482
workDate = new Date()
UTCDate = new Date()
UTCDate.setTime(workDate.getTime()+workDate.getTimezoneOffset()*60000)

function printTime(offset) {
    offset++;
    tempDate = new Date()
    tempDate.setTime(UTCDate.getTime()+3600000*(offset))
    timeValue = ((tempDate.getHours()<10) ? ("0"+tempDate.getHours()) : (""+tempDate.getHours()))
    timeValue += ((tempDate.getMinutes()<10) ? ("0"+tempDate.getMinutes()) : tempDate.getMinutes())
    timeValue += " hrs."
    return timeValue
    }
    var now = new Date()
    var seed = now.getTime() % 0xfffffff
    var same = rand(12)
</script>

Banff, Canada:
<script language="JavaScript">document.write(printTime("-7"))</script>

전체 코드 예

<html>

<head>
<script language="javascript" type="text/javascript">
//borrowed from echoecho
//http://www.echoecho.com/ubb/viewthread.php?tid=2362&pid=10482&#pid10482
workDate = new Date()
UTCDate = new Date()
UTCDate.setTime(workDate.getTime()+workDate.getTimezoneOffset()*60000)

function printTime(offset) {
offset++;
tempDate = new Date()
tempDate.setTime(UTCDate.getTime()+3600000*(offset))
timeValue = ((tempDate.getHours()<10) ? ("0"+tempDate.getHours()) : (""+tempDate.getHours()))
timeValue += ((tempDate.getMinutes()<10) ? ("0"+tempDate.getMinutes()) : tempDate.getMinutes())
timeValue += " hrs."
return timeValue
}
var now = new Date()
var seed = now.getTime() % 0xfffffff
var same = rand(12)
</script>

</head>

<body>
Banff, Canada:
<script language="JavaScript">document.write(printTime("-7"))</script>
<br>
Michigan:
<script language="JavaScript">document.write(printTime("-5"))</script>
<br>
Greenwich, England(UTC):
<script language="JavaScript">document.write(printTime("-0"))</script>
<br>
Tokyo, Japan:
<script language="JavaScript">document.write(printTime("+9"))</script>
<br>
Berlin, Germany:
<script language="JavaScript">document.write(printTime("+1"))</script>

</body>
</html>

이 코드는 브라우저 시간대로 형식화 된 Date 객체 를 반환합니다 .

Date.prototype.timezone = function () {
    this.setHours(this.getHours() + (new Date().getTimezoneOffset() / 60));
    return this;
}

이것은 나를 위해 일했습니다. 그래도 좋은 아이디어인지 확실하지 않습니다.

var myDate = new Date();
console.log('myDate:', myDate);   // myDate: "2018-04-04T01:09:38.112Z"

var offset = '+5';  // e.g. if the timeZone is -5

var MyDateWithOffset = new Date( myDate.toGMTString() + offset );   

console.log('MyDateWithOffset:', MyDateWithOffset); // myDateWithOffset: "2018-04-03T20:09:38.000Z"


timezone-js 패키지를 사용했습니다.

var timezoneJS  = require('timezone-js');
var tzdata = require('tzdata');

createDate(dateObj) {
    if ( dateObj == null ) {
        return null;
    }
    var nativeTimezoneOffset = new Date().getTimezoneOffset();
    var offset = this.getTimeZoneOffset();

    // use the native Date object if the timezone matches
    if ( offset == -1 * nativeTimezoneOffset ) {
        return dateObj;
    }

    this.loadTimeZones();

    // FIXME: it would be better if timezoneJS.Date was an instanceof of Date
    //        tried jquery $.extend
    //        added hack to Fiterpickr to look for Dater.getTime instead of "d instanceof Date"
    return new timezoneJS.Date(dateObj,this.getTimeZoneName());
},

이것은 최고의 솔루션입니다

사용 :

// TO ALL dates
Date.timezoneOffset(-240) // +4 UTC

// Override offset only for THIS date
new Date().timezoneOffset(-180) // +3 UTC

암호:

Date.prototype.timezoneOffset = new Date().getTimezoneOffset();

Date.setTimezoneOffset = function(timezoneOffset) {
  return this.prototype.timezoneOffset = timezoneOffset;
};

Date.getTimezoneOffset = function() {
  return this.prototype.timezoneOffset;
};

Date.prototype.setTimezoneOffset = function(timezoneOffset) {
  return this.timezoneOffset = timezoneOffset;
};

Date.prototype.getTimezoneOffset = function() {
  return this.timezoneOffset;
};

Date.prototype.toString = function() {
  var offsetDate, offsetTime;
  offsetTime = this.timezoneOffset * 60 * 1000;
  offsetDate = new Date(this.getTime() - offsetTime);
  return offsetDate.toUTCString();
};

['Milliseconds', 'Seconds', 'Minutes', 'Hours', 'Date', 'Month', 'FullYear', 'Year', 'Day'].forEach((function(_this) {
  return function(key) {
    Date.prototype["get" + key] = function() {
      var offsetDate, offsetTime;
      offsetTime = this.timezoneOffset * 60 * 1000;
      offsetDate = new Date(this.getTime() - offsetTime);
      return offsetDate["getUTC" + key]();
    };
    return Date.prototype["set" + key] = function(value) {
      var offsetDate, offsetTime, time;
      offsetTime = this.timezoneOffset * 60 * 1000;
      offsetDate = new Date(this.getTime() - offsetTime);
      offsetDate["setUTC" + key](value);
      time = offsetDate.getTime() + offsetTime;
      this.setTime(time);
      return time;
    };
  };
})(this));

커피 버전 :

Date.prototype.timezoneOffset = new Date().getTimezoneOffset()


Date.setTimezoneOffset = (timezoneOffset)->
    return @prototype.timezoneOffset = timezoneOffset


Date.getTimezoneOffset = ->
    return @prototype.timezoneOffset


Date.prototype.setTimezoneOffset = (timezoneOffset)->
    return @timezoneOffset = timezoneOffset


Date.prototype.getTimezoneOffset = ->
    return @timezoneOffset


Date.prototype.toString = ->
    offsetTime = @timezoneOffset * 60 * 1000
    offsetDate = new Date(@getTime() - offsetTime)
    return offsetDate.toUTCString()


[
    'Milliseconds', 'Seconds', 'Minutes', 'Hours',
    'Date', 'Month', 'FullYear', 'Year', 'Day'
]
.forEach (key)=>
    Date.prototype["get#{key}"] = ->
        offsetTime = @timezoneOffset * 60 * 1000
        offsetDate = new Date(@getTime() - offsetTime)
        return offsetDate["getUTC#{key}"]()

    Date.prototype["set#{key}"] = (value)->
        offsetTime = @timezoneOffset * 60 * 1000
        offsetDate = new Date(@getTime() - offsetTime)
        offsetDate["setUTC#{key}"](value)
        time = offsetDate.getTime() + offsetTime
        @setTime(time)
        return time

참고 URL : https://stackoverflow.com/questions/439630/create-a-date-with-a-set-timezone-without-using-a-string-representation



반응형