---
title: "Function: dateToEpochConversion"
description: Recursively change String Dates into Unix Epoch timestamps.
pubDate: 2026-08-17T09:53:44.266Z
antora:
  editUrl: https://github.com/couchbaselabs/docs-devex/edit/release/8.0/modules/eventing/pages/eventing-handler-dateToEpochConversion.adoc
  xref: xref:server:eventing:eventing-handler-dateToEpochConversion.adoc[]
---

[Consult the llms.txt file for a full list of contents](/llms.txt)
[View original HTML](/server/current/eventing/eventing-handler-dateToEpochConversion.html)

# Function: dateToEpochConversion

**Goal**: Recursively change String Dates into Unix Epoch timestamps.

* This function **dateToEpochConversion** will recursively convert string dates to a UNIX Epoch timestamp.
* The sample can convert to either seconds from Epoch or milliseconds from Epoch.
* In addition the sample optionally rename fields by adding \_ms or \_sec suffix (note, arrays will not be renamed).
* Requires Eventing Storage (or metadata collection) and a "source" collection.
* Will operate on all documents where doc.type === "my\_data\_type".

* dateToEpochConversion
* Input Data/Mutation
* Output Data/Mutation

```javascript
// To run configure the settings for this Function, dateToEpochConversion, as follows:
//
// Version 7.1+
//   "Function Scope"
//     *.* (or try bulk.data if non-privileged)
// Version 7.0+
//   "Listen to Location"
//     bulk.data.source
//   "Eventing Storage"
//     rr100.eventing.metadata
//   Binding(s)
//    1. "binding type", "alias name...", "bucket.scope.collection", "Access"
//       "bucket alias", "src_col",       "bulk.data.source",        "read and write"
//
// Version 6.X
//   "Source Bucket"
//     source
//   "MetaData Bucket"
//     metadata
//   Binding(s)
//    1. "binding type", "alias name...", "bucket",     "Access"
//       "bucket alias", "src_col",       "source", "read and write"

function convertStrToEpoch(key, val, control) {

    // We want to convert string dates to a Epoch tstamp, first we utilize
    // a regex to filter, then if that passes we use Date.parse(..)
    // to  convert string to numeric timestamps, finally if the last argument
    // is 'true' then add a suffix of "_ms" or "_sec" to the field name.

    // Date.parse("2009/06/29 13:30:10", "yyyy/MM/dd HH:mm:ss");
    // Date.parse("2020-06-24 09.55.22 -07:00", "yyyy-MM-dd HH:mm:ss Z");

    // uses a self explanatory control document as follows:

    // var control = [
    //    { "regx": /^\d\d\d\d-\d\d-\d\d \d\d:\d\d:\d\d.\d+$/g, "millis": true, "rename": true },
    //    { "regx": /^\d\d\d\d\/\d\d\/\d\d \d\d:\d\d:\d\d$/g, "millis": false, "rename": true }
    // ];

    for (var i=0;i<control.length;i++) {
    var regxres = val.match(control[i].regx);
    if (regxres !== null) {
        var dt = Date.parse(val);
        if (dt && dt !== null && !isNaN(dt)) {
            var suffix = "";
            var epochMs = dt // .getTime();
            if (key !== "" && control[i].rename) {
                if (control[i].millis) {
                    suffix = "_ms";
                } else {
                    suffix = "_sec";
                }
            }
            if (control[i].millis) {
                val = epochMs;
            } else {
                val = Math.round(epochMs / 1000);
            }
            return { "key": key + suffix, "val": val,  "epoch_ok": true };
        }
    }
    }
    return { "key": key, "val": val, "epoch_ok": false };
}

function converTsStringsToEpochNumbers(obj, control) {

    // This does a deepCopy or deepClone but applies convertStrToEpoch where needed

    // process terminal strings
    if (obj && typeof obj === 'string') {
        var retval = convertStrToEpoch("", obj, control);
        if (retval.epoch_ok) obj = retval.val;
        return obj;
    }
    if (!obj || typeof obj !== 'object') {
        return obj;
    }

    // process Object
    let newObj = {};
    if (Array.isArray(obj)) {
        newObj = obj.map(item => converTsStringsToEpochNumbers(item, control));
    } else {
        Object.keys(obj).forEach((k) => {
            var retval = { "key": k, "val": obj[k] };
            if (obj[k] && typeof obj[k] === 'string') {
                retval = convertStrToEpoch(k, obj[k], control);
            }
            return newObj[retval.key] = converTsStringsToEpochNumbers(retval.val, control);
        })
    }
    return newObj;
}

function OnUpdate(doc, meta) {
    if (doc.type !== "my_data_type") return;

    var rename_with_ms_or_sec = true;  // rename our fields
    // Apply four (4) different datetime search patterns across the entire document
    var control = [
        { "regx": /^\d\d\d\d-\d\d-\d\d \d\d:\d\d:\d\d.\d+$/g, "millis": true, "rename": true },
        { "regx": /^\d\d\d\d\/\d\d\/\d\d \d\d:\d\d:\d\d$/g, "millis": false, "rename": true },
        { "regx": /^\d\d\d\d-\d\d-\d\d \d\d:\d\d:\d\d.\d+ .\d\d:\d\d$/g, "millis": false, "rename": true },
        { "regx": /^\d\d\d\d\/\d\d\/\d\d \d\d:\d\d:\d\d .\d\d:\d\d$/g, "millis": true, "rename": true }
    ];
    var newdoc = converTsStringsToEpochNumbers(doc, control);

    // alias src_col to our source collection. Will work since rev 6.5+ allowed to be in r/w mode
    src_col[meta.id] = newdoc;
}
```

```json
INPUT: KEY my_data_type::1001

{
  "type": "my_data_type",
  "id": 1001,
  "datet1a": "2009/06/29 13:30:10",
  "datet1b": "2009/06/29 13:30:10",
  "datet1c": "2009/06/29 13:30:10 -07:00",
  "datet1d": "2009/06/29 13:30:10 -06:00",
  "datet2a": "2009-06-29 13:30:10.333",
  "datet2b": "2009-06-29 13:30:10.333",
  "datet2c": "2009-06-29 13:30:10.333 -07:00",
  "datet2d": "2009-06-29 13:30:10.333 -06:00",
  "subdoc_same_dates": {
    "datet1a": "2009/06/29 13:30:10",
    "datet1b": "2009/06/29 13:30:10",
    "datet1c": "2009/06/29 13:30:10 -07:00",
    "datet1d": "2009/06/29 13:30:10 -06:00",
    "datet2a": "2009-06-29 13:30:10.333",
    "datet2b": "2009-06-29 13:30:10.333",
    "datet2c": "2009-06-29 13:30:10.333 -07:00",
    "datet2d": "2009-06-29 13:30:10.333 -06:00",
    "subsubdoc_two_dates": {
      "datet1a": "2009/06/29 13:30:10",
      "datet1b": "2009/06/29 13:30:10",
      "dary": [
        "2009/06/29 13:30:10",
        "2009-06-29 13:30:10.333",
        { "datet1a": "2009/06/29 13:30:10" }
      ]
    }
  }
}
```

```json
UPDATED/OUTPUT: KEY my_data_type::1001

{
  "type": "my_data_type",
  "id": 1001,
  "datet1a_sec": 1246307410,
  "datet1b_sec": 1246307410,
  "datet1c_ms": 1246307410000,
  "datet1d_ms": 1246303810000,
  "datet2a_ms": 1246307410333,
  "datet2b_ms": 1246307410333,
  "datet2c_sec": 1246307410,
  "datet2d_sec": 1246303810,
  "subdoc_same_dates": {
    "datet1a_sec": 1246307410,
    "datet1b_sec": 1246307410,
    "datet1c_ms": 1246307410000,
    "datet1d_ms": 1246303810000,
    "datet2a_ms": 1246307410333,
    "datet2b_ms": 1246307410333,
    "datet2c_sec": 1246307410,
    "datet2d_sec": 1246303810,
    "subsubdoc_two_dates": {
      "datet1a_sec": 1246307410,
      "datet1b_sec": 1246307410,
      "dary": [
        1246307410,
        1246307410333,
        {
          "datet1a_sec": 1246307410
        }
      ]
    }
  }
}
```