A DAQFactory Express logging set fed by a LabJack UE9 writes its time column as a number, either in Excel format or in DAQFactory's native seconds format. There is no logging-set checkbox that turns that column into 02.08.2006 12:02:01. You get a readable column by building a String channel that one line of event script fills with FormatDateTime(), and adding that channel to the logging set. The alternative is to keep the numeric column and convert it in the analysis tool. The checks below show which path fits your installation and how to confirm the file is correct.
Where does the timestamp come from on its way to the text file?
Trace one sample from the hardware to the file:
- The UE9 returns a reading to the DAQFactory driver.
- DAQFactory stores the value in the channel's history and stamps it with a time. That time is a double-precision number held internally, not text.
- The logging set reads the channel histories. It lines the values up by time and writes one row per aligned timestamp.
- The file writer outputs the time column in the numeric format selected in the logging set, followed by the channel values, separated by the logging-set delimiter (comma by default).
Human-readable text never exists anywhere along this path. That is deliberate. A number sorts, subtracts, and queries directly. A date string also depends on the reader's locale: 02.08.2006 is 2 August in most of Europe and would be read as February 8 under US month-day-year order. When the day is 12 or less, the string alone cannot tell you which order was used. To get text into the file, you have to create it at step 2 as a separate channel so the logging set treats it like any other column.
Which number is in the time column right now?
Open an existing log file and read the first time value. Its magnitude tells you the format. The values below are derived from the two epochs and are rounded.
| Format | Unit and epoch | Approx. value, Aug 2006 | Approx. value, 2026 | Next check |
|---|---|---|---|---|
| Excel format | Days since 30 Dec 1899; the fraction is the time of day | ~38,900 | ~46,000 | Check 3: format the cell in the spreadsheet |
| DAQFactory / Windows seconds format | Seconds since 1 Jan 1970, with fractional seconds | ~1.15 × 109 | ~1.78 × 109 | Check 3: convert, or add the String channel |
If the value falls in neither range, the column is probably not time at all. Confirm which column the logging set writes first before you go further.
Can the analysis tool consume the numeric time directly?
This is the branch point. Most spreadsheet and statistics packages can convert a numeric date once, at import. If your tool can, keep the numeric column. It preserves sub-second resolution and has no locale ambiguity.
| Logged format | Conversion to a spreadsheet date | Display format to apply |
|---|---|---|
| Excel format | None. The value already is a spreadsheet date serial. | Custom DD.MM.YYYY hh:mm:ss (German-locale Excel uses TT.MM.JJJJ hh:mm:ss) |
| Seconds since 1970 |
=A2/86400+25569, where 86,400 is seconds per day and 25,569 is the day count from 30 Dec 1899 to 1 Jan 1970 |
Same as above |
Before you trust the conversion, compare one converted row against the PC clock time you noted when that sample was taken. If the result is off by a whole number of hours, the stored time and your display differ by a UTC or daylight-saving offset. Add or subtract hours/24 to correct it.
Take the String-channel branch when any of these apply:
- Operators open the raw file and need to read it directly.
- The downstream tool expects a text timestamp in a fixed pattern.
- You want to remove the per-file conversion step from every analysis.
Formatting one string per sample costs a PC almost nothing in CPU time.
How does a String channel carry a formatted time into the log?
A DAQFactory channel does not have to be backed by hardware. A channel of device type Test with I/O type String holds text values in its history, just as an analog channel holds numbers. Setting its Timing to 0 stops DAQFactory from polling it, so the channel only receives values that script pushes into it with AddValue().
The script goes in the Event of a real UE9 channel. A channel event runs each time that channel receives a new data point. Each UE9 reading therefore triggers one formatted string. MyChannel.Time[0] returns the timestamp of the newest value in that channel's history, because index 0 is always the most recent point.
| Setting on the new channel | Value | Reason |
|---|---|---|
| Channel name |
TheTime (any name works) |
This becomes the column header in the log |
| Device Type | Test |
No hardware I/O |
| I/O Type | String |
The history stores text, not numbers |
| Timing | 0 |
Not polled; filled only by the event script |
| Channel # / D# | Any value | Ignored for this use |
Put this line in the Event of the UE9 channel. Replace MyChannel with your channel's actual name:
theTime.AddValue(FormatDateTime("%c", MyChannel.Time[0]))
Pick a trigger channel that updates at the rate you want rows logged. If your UE9 channels run at different rates, attach the event to the channel that sets your logging cadence. A slower channel produces time strings for only some of the rows, and a faster one produces extra strings with no matching data.
Which format string gives dd.mm.yyyy hh:mm:ss, and will it collide with the delimiter?
%c outputs the date and time in the Windows regional format of the logging PC. On a German-locale machine that usually looks like 02.08.2006 12:02:01. Move the project to a PC with US settings and the same code writes month-first. If you want the file format to stay the same regardless of which PC runs it, spell the pattern out explicitly. FormatDateTime() uses the C-style strftime codes. The DAQFactory help file entry for FormatDateTime() lists the full set; check it against these:
| Desired output | Format string | Example |
|---|---|---|
| Locale default | %c |
Depends on the PC's regional settings |
| European fixed | %d.%m.%Y %H:%M:%S |
02.08.2006 12:02:01 |
TheTime.AddValue(FormatDateTime("%d.%m.%Y %H:%M:%S", MyChannel.Time[0]))
Use it when files feed a database or statistics package. Use the dotted European pattern when people read the file directly.
Next, check the delimiter. The logging set separates columns with a comma by default. If the formatted string contains a comma, a parser splits the timestamp into two columns and every column after it shifts by one. Neither pattern above contains a comma. %c can include one on some locales, so print it once and inspect the result.
On PCs that use a decimal comma, also check how the logging set writes numeric values. A decimal comma inside a comma-delimited file causes the same column shift. Switch the delimiter to tab or semicolon if that happens.
Why is the TheTime column empty, split, or misaligned?
| Symptom in the log file | Likely cause | Reading to take / fix |
|---|---|---|
| Time-string column is missing entirely | The String channel was never added to the logging set | Open the logging set's channel list and add TheTime
|
| Column header present, cells empty | The event is not firing, or the script errors out | Open the String channel's table view to see whether values arrive; check the command/alert window for script errors; confirm the channel name in the script matches exactly |
| Column is filled on only some rows | The trigger channel updates more slowly than the logged channels | Move the event to the channel that sets the logging rate |
| Time string and data appear on separate rows |
AddValue() stamps the string when the event runs, slightly after the reading, and the logging set does not treat the two as the same instant |
Loosen the logging set's time-alignment tolerance so points a few milliseconds apart share a row |
| Timestamp split across two columns | The format string contains the delimiter | Use an explicit comma-free format, or change the delimiter |
| Day and month swapped on another PC |
%c follows that PC's regional settings |
Replace %c with explicit codes |
| Readable time loses sub-second detail |
%S writes whole seconds only |
Keep the numeric time column in the file as well |
Keep both columns in the file. Leave the numeric time as the logging set's native first column and add TheTime beside it. People get a readable timestamp, and scripts keep a sortable, full-resolution value.
How do I build the readable time column and prove it matches the data?
- Stop the logging set so the file does not change structure mid-run.
- Create a new channel named
TheTime. Set Device TypeTest, I/O TypeString, and Timing0. Leave Channel # and D# at any value. - Open the UE9 channel that sets your logging cadence and go to its Event tab.
- Enter
TheTime.AddValue(FormatDateTime("%d.%m.%Y %H:%M:%S", MyChannel.Time[0])), replacingMyChannelwith that channel's name. Use%cinstead if you want the locale default. - Apply the changes. Open the
TheTimechannel table and confirm that a new string appears at each UE9 update. - Add
TheTimeto the logging set's channel list. Confirm the delimiter does not appear in the string. - Start the logging set and let it run for several update periods.
- Open the text file in a plain text editor, not a spreadsheet, so no import rules reformat anything. Check that every data row has a
TheTimecell and that each row has the same number of delimiters as the header. - Pick one row. Convert its numeric time with the formula from the conversion table. Confirm the result matches the
TheTimestring on that row to the second and matches the PC clock time recorded when the sample was taken.
FAQ
Can I get a readable timestamp in DAQFactory Express without any scripting?
Not from the logging set alone. It writes time only as an Excel-format or seconds-since-1970 number. Either convert that column in the analysis tool, or fill a String channel with one line of event script using FormatDateTime() and log that channel.
Does FormatDateTime("%c") produce the same format on every PC?
No. %c follows the Windows regional settings of the PC running DAQFactory, so a German PC and a US PC write day and month in different orders. For a fixed format, use explicit codes such as %d.%m.%Y %H:%M:%S.
Can I keep milliseconds when logging a readable time?
%S writes whole seconds, so the formatted string drops the fractional part DAQFactory stores internally. Keep the numeric time column in the same logging set so the sub-second value stays in the file.
How do I convert a DAQFactory seconds timestamp to an Excel date?
Use =A2/86400+25569 and apply a custom cell format such as DD.MM.YYYY hh:mm:ss. If the result is off by whole hours, correct the UTC or daylight-saving offset by adding or subtracting hours/24.