【问题标题】:Date as Int for "date key"日期作为“日期键”的 Int
【发布时间】:2012-01-12 20:34:29
【问题描述】:

我想知道如何在 Java 中创建一个表达式,该表达式采用格式为“1999-12-30 12:34:45”的日期变量并将其转换为包含“19991230”的 Int。

这可能是其他人会喜欢的,尤其是人们提取和清理数据以加载到数据仓库中。

我的猜测是需要更改日期模式,转换为字符串,截断第一部分(8 个字符)并转换为 int。

想法?

(更新) 我不好解释这个问题。 生成的 int 将作为日期维度的键/Fk id。应该执行类似的操作来创建时间维度的键。 int 将减少在存储这些 int 键的事实表中消耗的大小。查看相关答案:https://stackoverflow.com/a/8416548/1132571

【问题讨论】:

  • 你描述的操作是微不足道的。但是,我认为没有人会使用它。大多数人使用真实数据或 unixtime。
  • 为什么要将Date 存储为Integer
  • @mre:整数是整数。简单、小型(取决于)、跨平台。
  • 我认为你的意思是截断前 10 个字符或前 8 个数字。如果您以日期而不是字符串开头,为什么不从一开始就将其格式化为“yyyyMMdd”?
  • 源系统提供的格式为 yyyy-MM-dd hh:mm:ss,我希望有一个“单行”将其转换为 (1) 日期键(int) 和 (2 - 单独的问题) 另一个时间键 (int) 由 "hhmm" 作为 int 组成

标签: java date data-warehouse etl


【解决方案1】:

使用SimpleDateFormat 类很容易做到这一点。但是,正如其他人提到的那样,您可能应该将纪元时间戳存储为 Database TimeStamp 列,而不是将日期存储为 int 形式。以后用 SQL 操作数据时会出问题。

public static void main(String[] args) throws ParseException {
        String dateStr = "1999-12-30 12:34:45";
        String formatStr = "yyyy-MM-dd HH:mm:ss";
        String formatStrOther = "yyyyMMdd";
        Date testDate = null;
        SimpleDateFormat sdf= new SimpleDateFormat(formatStr);
        SimpleDateFormat sdfOther= new SimpleDateFormat(formatStrOther);
        sdf.setLenient(false);
        testDate = sdf.parse(dateStr);
        Integer otherDate = Integer.valueOf(sdfOther.format(testDate));
        System.out.println("Newly formatted date in int is: " + otherDate); //prints Newly formatted date in int is: 19991230

    }

【讨论】:

  • 而不是存储时间戳,日期维度的外键将使我能够访问除日期时间之外的其他一些内容。这就是为什么我想将日期转换为整数。日期键上的一些外部参考 a la Kimball:forum.kimballgroup.com/…
  • @Geuder - 好的。我上面提供的内容应该可以为您解决问题。
  • @Geuder 如果对您有帮助,请接受答案。您可以通过单击答案旁边的勾号来接受。这将鼓励您将来回答您的问题,为您赢得声誉积分,最重要的是您将获得良好的接受率。
【解决方案2】:

只需删除特殊字符,然后转换为 int

Integer.parseInt("1999-12-30 12:34:45".replaceAll("[- :]", ""));

在您的情况下,您只需要日期,而不是时间:

Integer.parseInt("1999-12-30 12:34:45".substring(0,10).replaceAll("-", ""));

我应该提到,这只有在原始格式正确的情况下才有效......而且它实际上很丑陋,我宁愿使用 long 和 getTime - 也许是 simpleDateFormat。你真的不想丢掉有用的数据!

【讨论】:

  • 我也想知道这与 SimpleDateFormat.parse() 相比如何,这肯定不那么冗长,但 RegEx 在 Java 中并不总是高效的。
  • 2147483647 是 Integer 的最大值,因此在日期和时间上调用 parseInt 都会导致 NumberFormatException。当然,使用该方法时,您可以将 int 替换为 long 或 BigInteger。
【解决方案3】:

getTime 会给你一个很长的信息,int 不够大。

http://docs.oracle.com/javase/1.4.2/docs/api/java/util/Date.html#getTime()

【讨论】:

  • 用户想要 int 中的 yearmonthday 格式,getTime() 返回自上一个 epoch 以来的毫秒数。不是一回事。
  • 嗯,这个想法是“清理”数据以供数据仓库使用...以无法在 SQL 中简单使用的格式存储日期对我来说不太有意义
【解决方案4】:

虽然我同意评论者认为这很奇怪,但如果我真的需要将日期转换为 long,我会使用 date.getTime(),它返回一个 long,表示自 01.01.1970 以来的毫秒数。

好东西是它可以很容易地变成日期(Java 有一个构造函数,我怀疑其他语言也有)

【讨论】:

    【解决方案5】:

    假设格式保持不变:

    String dateStr = "1999-12-30 12:34:45";
    dateStr = dateStr.substring(0, 10);
    dateStr = dateStr.replace("-", "");
    int n = Integer.parseInt(dateStr);
    System.out.println(n);
    

    打印:19991230

    【讨论】:

      【解决方案6】:

      你可以使用类似的东西:

      var dateObj=new Date("1999-12-30 12:34:45");
      

      然后您需要做的就是获取日期对象的值,如下所示:

      var timeStamp=dateObj.valueOf();
      

      这将为您提供自 1970 年以来的毫秒数,这是大多数计算机系统使用的通用时间系统。

      转回使用:

      var newTime=new Date(timeStamp);
      

      【讨论】:

        【解决方案7】:

        使用 SimpleDateFormat、SimpleDateFormat.parse、SimpleDateFormat.format 和 Integer.parseInt [http://docs.oracle.com/javase/7/docs/api/java/text/SimpleDateFormat.html]

        1) 创建一个 SimpleDateFormat 将字符串解析为 Date 对象

        2) 创建一个 SimpleDateFormat 将 Date 对象格式化为 in 的 String 表示形式

        3) 使用 Integer.parseInt 将新格式化的 String 转换为 int。

        但是,将日期存储为 int 用于仓储对我来说没有多大意义。

        我猜有一些限制阻止您使用 ISO 8601 格式的日期或字符串。

        【讨论】:

        • 就我而言,我已经有一个日期对象。您将如何创建一个包含解决方案的第 2 步和第 3 步的单列?
        • 此外,这不是“强制”此要求的限制。将日期维度的外键作为 int 内存有效且可索引 -> 分析速度。
        【解决方案8】:

        还有一个。 (我不喜欢解析字符串,日期太容易出错。;-))

        DateFormat format = new SimpleDateFormat("dd-MM-yyyy");
        
        Date d;
        try {
        
            d = (Date)format.parse("30-12-1999");
            Calendar c = Calendar.getInstance();
            c.setTime(d);
        
            int result = c.get(Calendar.YEAR) * 100*100 + 
                        (c.get(Calendar.MONTH) + 1) * 100 + 
                         c.get(Calendar.DAY_OF_MONTH);
        
            System.out.println(result);
        
        } catch (ParseException e) {
            e.printStackTrace();
        }
        

        【讨论】:

          【解决方案9】:

          感谢所有建议、意见和建议。 这就是我要找的:

          Integer.parseInt(new SimpleDateFormat("yyyyMMdd").format(row.date));
          

          row.date(来自 Talend Open Studio)包含我想要转换为 int 日期键的日期。

          【讨论】:

            【解决方案10】:

            在许多方面,您最好将日期键保留为日期,尽管您可能希望截断键的天数。如果您还需要实际的日期时间,请将其单独存储。造成这种情况的原因有很多,主要与日期算术有关。

            • 可以在事实表上计算日期范围,而无需结合日期维度。

            • 查询将返回日期 - 如果您只是对表进行临时查询,这将非常有效。

            • 可以选择“之前”、“之后”、“错误”的特殊值,因此它们仍然相当明显(“1800-01-01”、“9000-01-01”、“6666-01” -01' 等)。

            • 如果您不必涉及日期维度,则按日期或日期范围进行自联接会更有效。

            • 最重要的是,可以直接在表上进行日期算术,而无需针对维度进行连接。计算 '2012-01-15' 前 180 天的日期比计算 20120115 更容易。此外,SQL 没有从 20120015 到相应日期的本机转换,无需在维度中查找。

              李>

            【讨论】:

            • 我同意。如果可能,将日期与事实一起存储可能会很有用。
            猜你喜欢
            • 2020-10-03
            • 2018-12-13
            • 2022-11-22
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多