LoginSignup
3
3

More than 5 years have passed since last update.

エクセルのシリアル値から日付集計

Last updated at Posted at 2015-11-27

あるデータの日付集計を頼まれたのだが,値が日付どころかどう見てもunixtimeでもない。
こんな感じ。
40820.89445601852

どうやらエクセルのシリアル値がそのまんま入っているようだ。
データベースをいじらすに集計したいところ。

エクセルのシリアル値からunixtimeへの変換

Excelの日付(シリアル値)についてと、UNIX時間との変換 (JavaScript, VBA) - Qiitaに詳しく書かれているので参考にした。感謝
unixtimeは1970/01/01からの時間(今回はミリ秒とする),
excelのシリアル値は1900/01/01からの1日=1の値なので,
70(年)*365(日)+17(日 うるう年の分)+2(日 1969/12/31からの1日分と,謎の1900/02/29)
をexcelのシリアル値から引くことで,unixtrimeと起点が一緒になる。
あとは単位をミリ秒に合わせるだけ。

aggregationでフィールドと四則演算

aggregationを使うとき "$excel_serial" - 25569 みたいに
フィールドの値と四則演算するときは,それを行うオペレーターを用いる。

  {$add: [<値1>, <値2>]}       // 値1 + 値2
  {$subtract: [<値1>, <値2>]}  // 値1 - 値2
  {$multiply: [<値1>, <値2>]}  // 値1 * 値2
  {$divide: [<値1>, <値2>]}    // 値1 / 値2

aggregationで演算結果からISODateに変換

演算結果を直接new Date()でISODate型に変えようとすると

> db.excel_data.aggregate([{$project: {d: Date({$multiply: [{$subtract:["$excel_serial", (70*365+17+2)]}, 24*60*60*1000]})}}])
assert: command failed: {
    "errmsg" : "exception: FieldPath 'Fri Nov 27 2015 14:56:36 GMT+0900 (JST)' doesn't start with $",
    "code" : 16873,
    "ok" : 0
} : aggregate failed

こんな感じのエラーが出る。
これは一度new Date(0)で初期状態のISODate型をつくっておいて,
それとさっき計算したunixtimeの値を足し算することで回避できる。

ISODate型から日付だけ取り出す

フォーマットを指定して変換できる.これは便利。
$dateToString (aggregation) — MongoDB Manual 3.0

{$dateToString: {format: "%Y%m%d", date: <さっきつくったISODate()>

できたもの

db.excel_data.aggregate([
    {$project: {
        d:{$dateToString: {
            format: "%Y%m%d", 
            date: {
                $add: [
                    new Date(0),
                    {$multiply:[
                        {$subtract:["$excel_serial", 70*365+17+2]},
                        24*60*60*1000
                    ]}
                ]
            }
       }}
    }}, 
    {$group: {
        _id: "$d",
        count: {$sum: 1}
    }},
    {$out: "count_date"}
])

やったぜ。

3
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
3