diff --git a/src/core/config/Categories.js b/src/core/config/Categories.js index ea095649..2484b834 100755 --- a/src/core/config/Categories.js +++ b/src/core/config/Categories.js @@ -193,6 +193,8 @@ const Categories = [ "Translate DateTime Format", "From UNIX Timestamp", "To UNIX Timestamp", + "Windows Filetime to UNIX Timestamp", + "UNIX Timestamp to Windows Filetime", "Extract dates", ] }, diff --git a/src/core/config/OperationConfig.js b/src/core/config/OperationConfig.js index 0d6778fc..9115f0de 100755 --- a/src/core/config/OperationConfig.js +++ b/src/core/config/OperationConfig.js @@ -2261,6 +2261,32 @@ const OperationConfig = { } ] }, + "Windows Filetime to UNIX Timestamp":{ + description: "Converts a Windows Filetime timestamp to a datetime format", + run: DateTime.runFromFiletimeToUnix, + inputType: "string", + outputType: "string", + args: [ + { + name: "Output Units", + type: "Option", + value: DateTime.UNITS + } + ] + }, + "UNIX Timestamp to Windows Filetime":{ + description: "Parses a datetime string in UTC and returns the corresponding Windows Filetime timestamp", + run: DateTime.runToFiletimeFromUnix, + inputType: "string", + outputType: "string", + args: [ + { + name: "Input Units", + type: "Option", + value: DateTime.UNITS + } + ] + }, "Translate DateTime Format": { description: "Parses a datetime string in one format and re-writes it in another.

Run with no input to see the relevant format string examples.", run: DateTime.runTranslateFormat, diff --git a/src/core/operations/DateTime.js b/src/core/operations/DateTime.js index 523206b2..a7a3c483 100755 --- a/src/core/operations/DateTime.js +++ b/src/core/operations/DateTime.js @@ -1,3 +1,5 @@ +import {BigInteger} from "jsbn"; + /** * Date and time operations. * @@ -78,6 +80,58 @@ const DateTime = { }, + /** + * Converts a Windows FILETIME to Unix Epoch time. + * + * @author bwhitn [brian.m.whitney@outlook.com] + * @param {string} input + * @param {Object[]} args (not used) + * @returns {string} + */ + runFromFiletimeToUnix: function(input, args) { + let units = args[0]; + input = new BigInteger(input).subtract(new BigInteger("116444736000000000")); + if (units === "Seconds (s)"){ + input = input.divide(new BigInteger("10000000")); + } else if (units === "Milliseconds (ms)") { + input = input.divide(new BigInteger("10000")); + } else if (units === "Microseconds (μs)") { + input = input.divide(new BigInteger("10")); + } else if (units === "Nanoseconds (ns)") { + input = input.multiply(new BigInteger("100")); + } else { + throw "Unrecognised unit"; + } + return input.toString(); + }, + + + /** + * Converts a Unix Epoch time to Windows FILETIME. + * + * @author bwhitn [brian.m.whitney@outlook.com] + * @param {string} input + * @param {Object[]} args (not used) + * @returns {string} + */ + runToFiletimeFromUnix: function(input, args) { + let units = args[0]; + input = new BigInteger(input); + if (units === "Seconds (s)"){ + input = input.multiply(new BigInteger("10000000")); + } else if (units === "Milliseconds (ms)") { + input = input.multiply(new BigInteger("10000")); + } else if (units === "Microseconds (μs)") { + input = input.multiply(new BigInteger("10")); + } else if (units === "Nanoseconds (ns)") { + input = input.divide(new BigInteger("100")); + } else { + throw "Unrecognised unit"; + } + return input.add(new BigInteger("116444736000000000")).toString(); + }, + + /** * @constant * @default diff --git a/test/index.js b/test/index.js index dba360ca..dbf1393d 100644 --- a/test/index.js +++ b/test/index.js @@ -16,6 +16,7 @@ import "./tests/operations/ByteRepr.js"; import "./tests/operations/CharEnc.js"; import "./tests/operations/Code.js"; import "./tests/operations/Compress.js"; +import "./tests/operations/DateTime.js"; import "./tests/operations/FlowControl.js"; import "./tests/operations/Image.js"; import "./tests/operations/MorseCode.js"; diff --git a/test/tests/operations/DateTime.js b/test/tests/operations/DateTime.js new file mode 100644 index 00000000..7ee445ff --- /dev/null +++ b/test/tests/operations/DateTime.js @@ -0,0 +1,34 @@ +/** + * DateTime tests. + * + * @author bwhitn [brian.m.whitney@outlook.com] + * + * @copyright Crown Copyright 2017 + * @license Apache-2.0 + */ +import TestRegister from "../../TestRegister.js"; + +TestRegister.addTests([ + { + name: "Filetime to Unix", + input: "129207366395297693", + expectedOutput: "1276263039529769300", + recipeConfig: [ + { + op: "Windows Filetime to UNIX Timestamp", + args: ["Nanoseconds (ns)"], + }, + ], + }, + { + name: "Unix to Filetime", + input: "1276263039529769300", + expectedOutput: "129207366395297693", + recipeConfig: [ + { + op: "UNIX Timestamp to Windows Filetime", + args: ["Nanoseconds (ns)"], + }, + ], + }, +]);