Timestamp String with one-second resolution: fastest implementation?

I’m trying to determine the fastest way to add UTC time stamps with a resolution of 1 s to automated logs of data reading and processing. This is used frequently as data are read into memory and processed. Suggestions would be welcome; my questions are at the bottom.

Trial solutions below are adapted from Higher resolution DateTime/TimeStamp . The first two give higher-resolution time stamps than I need, but that’s fine for comparison purposes.

using AstroTime, BenchmarkTools, Dates, Base.Libc

timestamp0() = string(Dates.now(Dates.UTC))
timestamp1() = string(AstroTime.now()) # not UTC??

function timestamp2()
  t = Dates.unix2datetime(Dates.time())
  Y, M, D, h, m, s = year(t), month(t), day(t),
    hour(t), minute(t), second(t)
  Ys = lpad(Y, 4, "0")
  Ms = lpad(M, 2, "0")
  Ds = lpad(D, 2, "0")
  hs = lpad(h, 2, "0")
  ms = lpad(m, 2, "0")
  ss = lpad(s, 2, "0")
  return string(Ys, "-", Ms, "-", Ds, "T", hs, ":", ms, ":", ss)
end

I swear I’m 20 years rusty at C and not even fond of external calls, but then there’s this, adapted from https://www.juliabloggers.com/getting-the-value-of-a-pointer-in-julia/

mutable struct TBuf
  t::Base.RefValue{Int64}
  m::TmStruct
  b::Array{UInt8,1}
  f::String
  p::Ptr{UInt8}
  function TBuf()
    T = new(Ref{Int64}(0), TmStruct(), zeros(UInt8,20),
            "%FT%T", Ptr{UInt8}())
    T.p = pointer(T.b)
    return T
  end
end
const T = TBuf()

function timestamp3()
  ccall(:time, Nothing, (Ptr{Int64},), T.t)
  ccall(Sys.iswindows() ? :gmtime_s : :gmtime_r, Nothing,
        (Ptr{Int64}, Ref{TmStruct}), T.t, T.m)
  ccall(:strftime, Nothing,
        (Cstring, Cint, Cstring, Ref{TmStruct}),
        T.p, Int32(20), T.f, T.m)
  return unsafe_string(T.p)
end

Results

Intel® Core™ i7-6820HQ CPU @ 2.70GHz
15862 MiB RAM
Ubuntu 18.04 (bionic)
Julia 1.3.1

Method Mem t
timestamp0 912 B 701.199 ns
timestamp1 1.63 KB 3.610 μs
timestamp2 688 B 584.849 ns
timestamp3 48 B 313.776 ns

My questions

  1. Are the C calls in timestamp3() safe as written? Do I need to set appropriate return Types, even though they modify variables in-place, or can I leave as Nothing?
  2. Is a memory-resident structure with Ref and Ptr as fields OK, or is this a spectacularly bad idea? For example, are there gc issues?
  3. Any suggestions that I might have missed?

Thanks, and my apologies for the length of the post.