【问题标题】:JXL and Timezone writing an Excel编写 Excel 的 JXL 和时区
【发布时间】:2011-12-20 17:01:15
【问题描述】:

我尝试用 jxl 创建一个 Excel 工作表。 我的一个领域是日期,我住在 GMT+1 时区

我用这样的东西来做到这一点:

WritableCellFormat EXCEL_DATE_FORMATTER = new WritableCellFormat(new DateFormat("dd/MM/yyyy hh:mm"));
...
WritableCell cell = null;
cell = new jxl.write.DateTime(col, row, date);
cell.setCellFormat(EXCEL_DATE_FORMATTER);

日期格式正确,但值为 -1 小时(格林威治标准时间) 我试图找到一个解决方案,我发现了这个 http://www.andykhan.com/jexcelapi/tutorial.html#dates 但我不能将 SimpleDateFormat 传递给 DateCell。 有办法吗? 现在我使用 java.util.Calendar 添加一个小时,但这是一个可怕的解决方案。 感谢您的帮助!

【问题讨论】:

    标签: java timezone jxl


    【解决方案1】:

    jxl.write.DateTime 类有几个构造函数(参见API)。

    默认情况下,它将使用您的系统时区来修改日期。您可以将 jxl.write.DateTime.GMTDate 对象传递给构造函数以禁用此功能。这是您应该使用的代码:

    WritableCell cell = null;
    cell = new jxl.write.DateTime(col, row, date, DateTime.GMT);
    

    【讨论】:

    • 感谢您的回答,但问题仍然出现:如果我使用日期并在构造函数中放置 DateTime.GMT,则小时为 GMT,如果我不放置 DateTime.GMT 为格林威治标准时间。似乎 DateTime 仅使用 GMT 而不是我的时区...
    【解决方案2】:

    昨天我遇到了同样的问题。我住在 CET 时区(中欧时间),DateTime 单元的简单创建将时间移动了大约一小时。

    起初我尝试按照官方教程中的建议将时区设置为GMT

    final DateFormat valueFormatDate = new DateFormat( "dd.MM.yyyy HH:mm" );
    valueFormatDate.getDateFormat().setTimeZone( TimeZone.getTimeZone( "GMT" ) );
    

    它似乎不起作用。时间修改还是一样的。所以我尝试设置正确的时区以匹配 Date 对象中的时区。

    final DateFormat valueFormatDate = new DateFormat( "dd.MM.yyyy HH:mm" );
    valueFormatDate.getDateFormat().setTimeZone( TimeZone.getTimeZone( "CET" ) );
    

    这完全符合我的预期。但是事情并不太容易,除了CET时区还有CEST(中欧夏令时)将时间移动了大约一个小时。当我尝试在 CEST 时间使用日期时,它没有再次起作用,因为在预期的基础上增加了一小时。我想为他们设置“CEST”时区而不是“CET”是一种解决方案,但我不知道如何从Calendar 获取正确的时区,它总是返回中欧。

    无论如何,我最终使用了一个不太好,但工作可靠的解决方案。

    • 我有一个工厂方法让日期单元格在一个地方进行配置
    • 在该方法中,我首先将给定的 Date 转换为 GMT 时区
    • 将时区格式设置为 GMT
    • DateTime 单元格上禁用时区修改。

    这些步骤并非绝对干净,但它适用于 CET 和 CEST 日期。最终代码在这里:

    public class DateUtils {
    
        // formatter to convert from current timezone
        private static final SimpleDateFormat DATE_FORMATTER_FROM_CURRENT = new SimpleDateFormat( "yyyy-MM-dd HH:mm:ss" );
    
        // formatter to convert to GMT timezone
        private static final SimpleDateFormat DATE_FORMATTER_TO_GMT = new SimpleDateFormat( "yyyy-MM-dd HH:mm:ss" );
    
        static {
            // initialize the GMT formatter
            final Calendar cal = Calendar.getInstance( new SimpleTimeZone( 0, "GMT" ) );
            DATE_FORMATTER_TO_GMT.setCalendar( cal );
        }
    
        public static Date toGMT( final Date base ) {
            try {
                // convert to string and after that convert it back
                final String date = DATE_FORMATTER_FROM_CURRENT.format( base );
                return DATE_FORMATTER_TO_GMT.parse( date );
    
            } catch ( ParseException e ) {
                log.error( "Date parsing failed. Conversion to GMT wasn't performed.", e );
                return base;
            }
        }
    }
    

    还有一个工厂方法

    /** builds date cell for header */
    static WritableCell createDate( final int column, final int row, final Date value ) {
        final DateFormat valueFormatDate = new DateFormat( "dd.MM.yyyy HH:mm" );
        valueFormatDate.getDateFormat().setTimeZone( TimeZone.getTimeZone( "GMT" ) );
        final WritableCellFormat formatDate = new WritableCellFormat( valueFormatDate );
    
        // create cell
        return new DateTime( column, row, toGMT( value ), formatDate, DateTime.GMT );
    }
    

    【讨论】:

    • 您的 createDate() 代码在概念上是错误的,因为 Excel/JXL 每个文件只允许有限数量的单元格格式。添加一定数量的单元格后,此类代码将失败。相反,应该预先创建一组格式,然后使用它们,而不是每次都创建一个新格式。
    • @PavelVlasov 我不认为这是“概念上的错误”,但是,我不知道这个限制。随时提议对帖子进行编辑。我很乐意合并它们。
    猜你喜欢
    • 1970-01-01
    • 2015-04-23
    • 1970-01-01
    • 1970-01-01
    • 2011-03-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多