Unix Hex Timestamp Converter — Hex/Decimal Seconds or Milliseconds ↔ Date
Display & Quick Actions
Results always include UTC; this controls the extra local view.
Override if your source is known to be seconds or ms.
1) Hex / Decimal Unix Timestamp → Date
Hex with/without 0x is accepted. Negative values supported.
2) Date → Unix Timestamp (Hex & Decimal)
Interpreted in your current local time zone.
If an offset is provided, it will be respected.
About Unix Hex Timestamps
A Unix timestamp is the number of seconds (or milliseconds) since 1970-01-01T00:00:00Z.
Many tools and logs render this number in hexadecimal.
This converter accepts hex (with or without 0x) or decimal, detects whether the value is in
seconds or milliseconds, and shows both formats.
- Auto-detect: Large magnitudes (≈ ≥ 1e11 or ≥ 2³²) are treated as milliseconds; smaller as seconds. You can override.
- Signed / negative: Values before 1970 (negative) are supported; seconds are floored for negatives.
- Precision: Internals use
BigIntto avoid rounding. Display is to millisecond precision.
Unix Hex Timestamp: Code Snippets & How-To
A Unix timestamp represents seconds (or milliseconds) since 1970-01-01T00:00:00Z.
Many logs use hexadecimal (with or without a 0x prefix). These examples show how to parse
hex/decimal, auto-detect seconds vs milliseconds, and convert to human-readable dates.
Rule of thumb
- If the absolute value is ≳
1e11, it’s likely milliseconds; otherwise seconds. - Negative values (before 1970) are valid; floor division is required when deriving seconds from ms.
JavaScript (Browser/Node)
function parseBigIntFlexible(s) {
s = s.trim();
if (/^-?0x[0-9a-f]+$/i.test(s)) return BigInt(s);
if (/^-?[0-9a-f]+$/i.test(s) && /[a-f]/i.test(s)) return BigInt('0x'+s.replace(/^-/,''));
if (/^-?\d+$/.test(s)) return BigInt(s);
throw new Error('Invalid hex/decimal integer');
}
function unitAuto(bi) {
const abs = bi < 0n ? -bi : bi;
return abs >= 100_000_000_000n ? 'ms' : 's';
}
function floorDiv(a, b) { // floor for negatives
const q = a / b, r = a % b;
return (r === 0n || (a >= 0n) === (b >= 0n)) ? q : q - 1n;
}
// Hex/dec → Date
function hexUnixToDate(s, unit = 'auto') {
let bi = parseBigIntFlexible(s);
if (unit === 'auto') unit = unitAuto(bi);
const ms = unit === 's' ? bi * 1000n : bi;
const max = 8_640_000_000_000_000n;
const clamped = ms > max ? max : (ms < -max ? -max : ms);
return new Date(Number(clamped));
}
// Date → hex/dec (seconds & milliseconds)
function dateToUnixHex(date = new Date()) {
const ms = BigInt(date.getTime());
const sec = floorDiv(ms, 1000n);
return {
seconds_dec: sec.toString(),
seconds_hex: '0x'+sec.toString(16).toUpperCase(),
millis_dec: ms.toString(),
millis_hex: '0x'+ms.toString(16).toUpperCase()
};
}
Python 3
import datetime, math, re
HEX_RE = re.compile(r'^-?(0x)?[0-9a-f]+$', re.IGNORECASE)
def parse_int_flexible(s: str) -> int:
s = s.strip()
if not s:
raise ValueError("empty input")
if s.lower().startswith('-0x'):
return -int(s[3:], 16)
if s.lower().startswith('0x'):
return int(s, 16)
if HEX_RE.match(s) and any(c.isalpha() for c in s):
return int(s, 16) if not s.startswith('-') else -int(s[1:], 16)
return int(s, 10)
def unit_auto(v: int) -> str:
return 'ms' if abs(v) >= 100_000_000_000 else 's'
def hex_unix_to_datetime(s: str, unit: str = 'auto') -> datetime.datetime:
v = parse_int_flexible(s)
if unit == 'auto':
unit = unit_auto(v)
ms = v if unit == 'ms' else v * 1000
# timezone-aware UTC datetime
return datetime.datetime.fromtimestamp(ms / 1000, tz=datetime.timezone.utc)
def datetime_to_unix(dt: datetime.datetime = None):
if dt is None:
dt = datetime.datetime.now(datetime.timezone.utc)
if dt.tzinfo is None:
dt = dt.astimezone() # local -> aware
ms = int(dt.timestamp() * 1000)
sec = math.floor(ms / 1000) # floor for negatives
return {
'seconds_dec': str(sec),
'seconds_hex': hex(sec),
'millis_dec': str(ms),
'millis_hex': hex(ms)
}
C (portable)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <inttypes.h>
static int is_hexlike(const char *s){
if (!s || !*s) return 0;
if (s[0]=='-' && s[1]) s++;
if (s[0]=='0' && (s[1]=='x' || s[1]=='X')) return 1;
for (const char *p=s; *p; ++p) if ((*p>='a' && *p<='f') || (*p>='A' && *p<='F')) return 1;
return 0;
}
int main(int argc, char **argv){
if (argc < 2){ fprintf(stderr, "usage: %s <hex|dec> [s|ms]\n", argv[0]); return 1; }
const char *in = argv[1];
const char *unit = (argc >= 3) ? argv[2] : "auto";
int isneg = (in[0]=='-');
if (isneg && in[1]=='0' && (in[2]=='x' || in[2]=='X')) in += 3;
char *end = NULL;
int base = is_hexlike(in) ? 16 : 10;
long long sign = isneg ? -1 : 1;
unsigned long long mag = strtoull(isneg ? in+1 : in, &end, base);
long long val = (long long)(sign * (long long)mag);
const char *mode = unit;
if (strcmp(mode,"auto")==0){
mode = ( llabs(val) >= 100000000000LL ) ? "ms" : "s";
}
long long ms = (strcmp(mode,"s")==0) ? val * 1000LL : val;
time_t secs = (time_t)(ms/1000LL - ((ms<0 && ms%1000LL)!=0)); // floor for negatives
struct tm tm_utc;
gmtime_r(&secs, &tm_utc);
char buf[64];
strftime(buf, sizeof(buf), "%Y-%m-%dT%H:%M:%SZ", &tm_utc);
printf("UTC ISO8601: %s\n", buf);
printf("UNIX seconds dec: %lld\n", (long long)secs);
printf("UNIX seconds hex: 0x%llX\n", (unsigned long long)secs);
printf("UNIX millis dec: %lld\n", ms);
printf("UNIX millis hex: 0x%llX\n", (unsigned long long)ms);
return 0;
}
C# (.NET)
using System;
using System.Globalization;
static class UnixHex {
static bool IsHexLike(string s) => s.StartsWith("0x", true, CultureInfo.InvariantCulture) || s.IndexOfAny("abcdefABCDEF".ToCharArray()) >= 0;
public static DateTimeOffset ParseToUtc(string s, string unit = "auto"){
s = s.Trim();
bool neg = s.StartsWith("-");
string core = s.StartsWith("-0x", true, CultureInfo.InvariantCulture) ? s.Substring(3)
: s.StartsWith("0x", true, CultureInfo.InvariantCulture) ? s.Substring(2)
: s;
long val = Convert.ToInt64((IsHexLike(s)) ? (neg ? "-" + Convert.ToInt64(core,16).ToString() : Convert.ToInt64(core,16).ToString())
: s, 10);
string mode = unit;
if (mode=="auto") mode = (Math.Abs(val) >= 100_000_000_000L) ? "ms" : "s";
long ms = (mode=="s") ? val*1000L : val;
return DateTimeOffset.FromUnixTimeMilliseconds(ms);
}
}
Go
package main
import (
"fmt"
"strconv"
"strings"
"time"
)
func parseIntFlexible(s string) (int64, error) {
s = strings.TrimSpace(s)
neg := strings.HasPrefix(s, "-")
core := s
if strings.HasPrefix(strings.ToLower(s), "-0x") { core = s[3:]; neg = true }
if strings.HasPrefix(strings.ToLower(s), "0x") { core = s[2:] }
base := 10
if strings.ContainsAny(core, "abcdefABCDEF") { base = 16 }
u, err := strconv.ParseUint(strings.TrimPrefix(core, "-"), base, 64)
if err != nil { return 0, err }
if neg { return -int64(u), nil }
return int64(u), nil
}
func unitAuto(v int64) string {
if v < 0 { v = -v }
if v >= 100_000_000_000 { return "ms" }
return "s"
}
func main() {
v, _ := parseIntFlexible("0x6512BD00")
mode := unitAuto(v)
if mode == "s" { v = v * 1000 }
t := time.UnixMilli(v)
fmt.Println(t.UTC().Format(time.RFC3339Nano))
}
Java / Kotlin
// Java
import java.time.*;
import java.util.*;
public class UnixHex {
static boolean isHexLike(String s){
return s.startsWith("0x") || s.matches(".*[A-Fa-f].*");
}
static long parseFlexible(String s){
s = s.trim();
boolean neg = s.startsWith("-");
String core = s.startsWith("-0x") ? s.substring(3) : (s.startsWith("0x") ? s.substring(2) : s);
long v = isHexLike(s) ? Long.parseUnsignedLong(core,16) : Long.parseLong(core,10);
return neg ? -v : v;
}
static String unitAuto(long v){ return Math.abs(v) >= 100_000_000_000L ? "ms" : "s"; }
public static void main(String[] args){
long v = parseFlexible("5F5E100");
String mode = unitAuto(v);
long ms = mode.equals("s") ? v*1000L : v;
Instant inst = Instant.ofEpochMilli(ms);
System.out.println(inst.toString()); // ISO-8601 UTC
}
}
Rust
use chrono::{DateTime, Utc, TimeZone};
fn parse_flexible(s: &str) -> i128 {
let s = s.trim();
let neg = s.starts_with('-');
let core = s.strip_prefix("-0x").or_else(|| s.strip_prefix("0x")).unwrap_or(s);
let mut v: i128 = if s.contains(|c: char| c.is_ascii_hexdigit() && c.is_ascii_alphabetic()) {
i128::from_str_radix(core, 16).unwrap()
} else { core.parse().unwrap() };
if neg { v = -v }
v
}
fn unit_auto(v: i128) -> 'static str { if v.abs() >= 100_000_000_000 { "ms" } else { "s" } }
fn main(){
let v = parse_flexible("0x0000018EDDDEAD");
let unit = unit_auto(v);
let ms: i128 = if unit == "s" { v * 1000 } else { v };
let secs = (ms.div_euclid(1000)) as i64; // floor
let nsec = ((ms.rem_euclid(1000)) * 1_000_000) as u32;
let dt: DateTime<Utc> = Utc.timestamp_opt(secs, nsec).unwrap();
println!("{}", dt.to_rfc3339_opts(chrono::SecondsFormat::Millis, true));
}
PHP
<?php
function parse_int_flexible(string $s): int {
$s = trim($s);
if (stripos($s, '-0x') === 0) return -intval(substr($s,3), 16);
if (stripos($s, '0x') === 0) return intval(substr($s,2), 16);
if (preg_match('/[a-f]/i', $s)) return intval($s, 16);
return intval($s, 10);
}
function unit_auto(int $v): string {
return (abs($v) >= 100_000_000_000) ? 'ms' : 's';
}
$v = parse_int_flexible('0x6512BD00');
$mode = unit_auto($v);
$ms = ($mode === 's') ? $v * 1000 : $v;
$dt = (new DateTimeImmutable('@' . intdiv($ms,1000)))->setTimezone(new DateTimeZone('UTC'));
echo $dt->format('c'); // ISO-8601 UTC
Ruby
def parse_int_flexible(s)
s = s.strip
return -s[3..].to_i(16) if s.downcase.start_with?('-0x')
return s[2..].to_i(16) if s.downcase.start_with?('0x')
return s.to_i(16) if s =~ /[a-f]/i
s.to_i
end
def unit_auto(v) = v.abs >= 100_000_000_000 ? 'ms' : 's'
v = parse_int_flexible('5F5E100')
mode = unit_auto(v)
ms = mode == 's' ? v * 1000 : v
t = Time.at(ms / 1000.0).utc
puts t.iso8601(3)
Bash (GNU coreutils)
# Hex/dec -> ISO UTC (seconds assumed; set UNIT=ms for millis)
IN="${1:-0x6512BD00}"
UNIT="${2:-auto}"
# normalize to decimal
if [[ "$IN" =~ ^-?0x[0-9a-fA-F]+$ ]]; then
DEC=$((IN)) # bash can parse 0x...
elif [[ "$IN" =~ [a-fA-F] ]]; then
DEC=$((16#$IN))
else
DEC=$IN
fi
if [[ "$UNIT" == "auto" ]]; then
ABS=${DEC#-}
[[ ${#ABS} -ge 11 ]] && UNIT=ms || UNIT=s
fi
if [[ "$UNIT" == "ms" ]]; then
SEC=$(( DEC / 1000 ))
else
SEC=$DEC
fi
date -u -d "@$SEC" +"%Y-%m-%dT%H:%M:%S%z"