Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/373.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 在DST期间转换为GMT会出现问题_Java - Fatal编程技术网

Java 在DST期间转换为GMT会出现问题

Java 在DST期间转换为GMT会出现问题,java,Java,我在现有的应用程序中遇到了一个问题,即员工输入的时间(使用time clock应用程序从其组织/商店输入)首先转换为GMT,然后存储在DB中。对于显示回,以GMT为单位的时间被转换回存储本地时区并显示。在大多数情况下,这可以正常工作,但当时区移动到DST时则不行,反之亦然 让我更具体一点。假设商店的标准时区为GMT-8,员工在早上08:00打卡,因此时间转换为GMT,即16:00,然后存储在DB中。 转换过程首先将这个上午08:00转换为存储本地时间,以某种方式给出 17:00CET,然后这个1

我在现有的应用程序中遇到了一个问题,即员工输入的时间(使用time clock应用程序从其组织/商店输入)首先转换为GMT,然后存储在DB中。对于显示回,以GMT为单位的时间被转换回存储本地时区并显示。在大多数情况下,这可以正常工作,但当时区移动到DST时则不行,反之亦然

让我更具体一点。假设商店的标准时区为GMT-8,员工在早上08:00打卡,因此时间转换为GMT,即16:00,然后存储在DB中。 转换过程首先将这个上午08:00转换为存储本地时间,以某种方式给出 17:00CET,然后这个17:00CET被转换成GMT,它给出16:00CET

但如果我们以3月31日为例,当DST发生时,凌晨02:00变为凌晨03:00。假设雇员在18:00(3月30日)打卡,在第一次转换为本地时返回我04:00 AM CEST,然后当我将其转换为GMT时返回03:00 CEST。所以,当把它转换回来的时候,这是19:00,这是不正确的。 设计表明,本地时间转换为UTC,然后存储在数据库中,但如果仍然是UTC,则应存储凌晨02:00,而不是凌晨03:00,因为GMT/UTC没有DST

用于进行转换的代码是:

步骤1

final Date localPunchDateTime = R3ValConverter.convertFromTimeZone(teData.m_dtTm,  
                                               TimeZone.getTimeZone("GMT-8"));
步骤2

teData.m_dtTm = R3ValConverter.convertToGMT( localPunchDateTime );
R3ValConverter.java

public static Date convertFromTimeZone(final Date dtSrc, final TimeZone tzSrc)
    {

        final SISDateTime dtTmTemp = new SISDateTime(dtSrc, TimeZone.getDefault());
        final SISDateTime dtTmSrc = new SISDateTime( dtTmTemp.getYear(), dtTmTemp.getMonth(), 
                                                     dtTmTemp.getDate(), dtTmTemp.getHour(), 
                                                     dtTmTemp.getMinute(), dtTmTemp.getSecond(), 
                                                     tzSrc );

        return dtTmSrc.toDate();                                                       
    }
SISDateTime

GregorianCalendar m_cal;

public SISDateTime(Date dt, TimeZone tz) throws SISDateTimeException
    {

        m_cal = new GregorianCalendar(tz);
        m_cal.setTime(dt);
        resetMillis();
    }
另一个SISDateTime方法也使用相同的GregorianCalendar


我真的很感激在这方面的任何帮助。我在这里假设我们在第一步中遇到了一些问题,但目前还不知道有什么好的解决办法

您必须将UTC+当前偏移量(以秒为单位)从本地时间存储到数据库中的UTC。 因此,如果要保留本地时间,则始终需要一对(Utc时间,偏移量)


然后您使用从GMT设置的时区偏移量(或命名为simmiliar)

我们的偏移量在标准时间为8,在DST为7,但如果我举我的例子,我们在18:00打孔,并将其存储为03:00 AM(转换为GMT后),那么在重新转换期间它不起作用,因为03:00-8(偏移量)给出19:00。您不应将其存储为03:AM,应将其存储为自1.1.1970(unix时间)起的utc毫秒或秒长值。在18:00和凌晨3点之间,有9小时,而不是8小时!嗨,亚历克斯,非常感谢你的投入。但是在创建日期对象之前,如何获取UTC毫秒数呢。因为如果我创建一个date对象,那么它会自动将02:00AM更改为03:00AM,然后如果我使用getTime()方法获取毫秒,那么它仍然会给出对应于03:00AM而不是02:00AM的值。非常感谢您的帮助..new Date().getTimeStamp()是自1970年1月1日以来的一个以UTC毫秒为单位的长值(请参见日期上的javadoc)将此长值与当前时区差一起存储到UTC。在使用任何toString()方法之前,必须确保电脑的时区设置正确,或者必须在SimpleDataFormat上显式指定时区