Handling simple calendar dates in Qlik is "usually straightforward". Timestamps, on the other hand are a different story. Fractions of a day, time-zone offsets, and “why won’t this sort?” moments can slow you down when developing an app.
In this blog post, I compiled 7 tips that can help you when dealing with Timestamps in Qlik.
1- Know Your Duals
Every Qlik timestamp has two sides:
Numeric side:days since 1899-12-30 (midnight = whole number)
Text side: the display mask Qlik generates
Think of the numeric part as the barcode and the text mask as the price tag.Scanning (calculations) cares only about the barcode; shoppers (users) care only about the tag.
Num(MyTS) // 45435.6542 (barcode)
Text(MyTS) // 2024-05-22 15:42:05 (tag)
Purpose
Example
FormattersTimestamp() / Date() / Time()
Change only the display text (tag)
Date(MyTS, 'MMM-YYYY') → “May-2024”
InterpretersTimestamp#() / Date#() / Time#()
Take raw text, build a new dual value, i.e. create the barcode.
Timestamp#('2024-05-22 15:42', 'YYYY-MM-DD hh:mm')→ dual value:- numeric:45435.65417- text:“2024-05-22 15:42”
Usually, issues with filters not working etc... will come from loading a timestamp as plain text and trying to format it later, changing only the "tag", never creating the "barcode".
2- Parse Once, Keep the Raw Text
Raw timestamps often land in your Qlik Sense App in different ways:
2025-05-23 14:31
5/23/25 2:31 PM
Unix epochs
Excel serials
etc...
Instead of trying to print them in a pretty way everywhere, you can instead:
Interpret the text a single time in the load script.
Store the parsed dual in a clean field (TS).
Keep the raw field off to the side for future re-parse.
LOAD
RawTS, // original column
Timestamp#(RawTS,'YYYY-MM-DD hh:mm:ss') AS TS // dual value
...
You can use "TS" for date calculations, for instance:- Floor(TS) AS OrderDate- Frac(TS) AS TimeKey
and keep "RawTS" hidden for QA, or re-parsing later.
3-Floor() + Frac() — Split Calendar and Clock
Timestamps captured to the second (or millisecond) contain far more detail than most analyses need.Using that raw granularity in filter panes or chart axes can crowd the UI with millions of distinct values and add unnecessary processing overhead, so abetter approach would be tosplit each timestamp into a date part and a time part so you can control it better
Function
Example result
Why?
OrderDate
Floor(TS)
2024-05-22
Links neatly to your master calendar—great for YTD, MoM, etc...
TimeKey
Frac(TS)
0.60486… (14:31)
Lets you build a small “clock” dimension for charts
LOAD
Floor(TS) AS OrderDate, // 2024-05-22
Round( Frac(TS), 1/1440 ) AS TimeKey_1min // 00:00 … 23:59
...
Why round?
Minute precision (1/1440 of a day) keeps the time dimension at 1440 values, this is perfect for charts, while OrderDate links neatly to your master calendar.
Clearer visuals: users choose “14:30” instead of scrolling through every second.
Predictable model size: 1440 rows in a minute-level time table, regardless of how much fact data you load.
Flexible math: the original TS is still there if you need second-level calculations.
For 15-min blocks, you'd do this:
Round( Frac(TS), 1/96 ) AS TimeKey_15min
4- Master Time Table
After you’ve split the timestamp into Date and TimeKey, you still need a small lookup table so charts can show friendly labels like “14 : 30.” That’s where a Master Time table comes in. Below, we generate exactly one row per minute, no more no less, so that our app gets a clean predictable clock dimension.
MasterTime:
LOAD
Round(IterNo()/1440,1/1440) AS TimeKey, // numeric 0–0.9993
Time(Round(IterNo()/1440,1/1440),'hh:mm') AS TimeLabel // 00:00 … 23:59
AUTOGENERATE 1440; // 24 h × 60 m
Explanation
IterNo()
Produces 0 … 1439 during AUTOGENERATE.
/ 1440
Turns each integer into the fraction of a day (1 = 24 h).
Round(…, 1/1440)
Rounds the fraction exactly on the minute boundary.
Time(…, 'hh:mm')
Formats the fraction as “00:00”, “00:01”, … “23:59”.
Need 15-minute buckets? Change 1440to 96 and 1/1440 to 1/96.
Check out Hic's blog post here for more in-depth information on this topic.
5- Converting Odd Formats (Unix Epoch & Excel Serial)
Not every data source delivers nice ISO date strings. Two formats you'll encounter most of the time:
What it means
Typical sources
Unix Epoch
An integer that counts seconds since 1970-01-01 00:00 UTC.Example 1716460800 is 2024-05-23 00:00 UTC
REST APIs, server logs, Kafka streams etc...
Excel Serial
A decimal that counts days since “1899-12-30 00:00”(Excel's day 0).Example 45435.75 is 2024-05-22 18:00
CSVs saved from Excel etc...
Load once, store as a proper dual, format later however you like.
// Unix Epoch (seconds) to Qlik timestamp
(Epoch / 86400) + 25569 AS TS_UTC // 86400 = sec per day
// Excel Serial to Qlik timestamp
ExcelSerial + Date#('1899-12-30') AS TS_Excel
Why 25569?-> That's the number of days between Qlik (& Excel)'s day 0 (1899-12-30) and Unix's day 0 (1970-01-01).
If you need a static timezone conversion? Add or subtract the offset in days:
(Epoch/86400)+25569 + (-4/24) AS TS_Local // convert to UTC-4
6- Turning Raw Seconds into Readable Durations with Interval()
When you subtract two timestamps Qlik gives you a fraction of a day and gives you something like:0.0027. But this doesn't really tell you the actual duration. You probably would understand something like this instead: 00:03:55.
That’s what the Interval() function is for, to convert numeric time spans into clean, readable timestamps.
// Average call duration → 03:55
Interval( Avg(EndTS - StartTS) , 'hh:mm' )
If you need the raw number too, you can pair Interval() with Num():
// friendly + raw seconds
Interval(Avg(EndTS - StartTS),'hh:mm') AS AvgDuration,
Num( Avg(EndTS - StartTS) * 86400 ) AS SecDuration
The result: The dashboard objects show03:55while any export still carries the raw value 222 seconds for downstream math.
Interval() is the quickest way to turn fractions of a day into durations everyone understands.
7- Applying a Simple Time-Zone Offset
Qlik stores every timestamp as a serial day-count with no built-in timezone. If your source data arrives in UTC but end users need to view time in Eastern Time, you can apply a static offset right in the load script:
// 1 hour = 1/24 of a day
LET vOffset = -4 / 24; // EST (UTC - 4 hours)
...
LOAD
UTC_TS,
UTC_TS + $(vOffset) AS LocalTS
...
Result:LocalTS shows 08:00 when UTC_TS is 12:00.
When a static shift is enough
Historical data analyses (offset never changes).
Systems that log in a single, known zone.
Handling daylight-saving shifts
If you need results for different regions that switch between standard and daylight time:
How
ConvertToLocalTime()
ConvertToLocalTime(UTC_TS, 'US/Eastern', 1)More info on the help docs
- Built-in Qlik function- Pass “1” to auto-adjust for DST.
Handle at the source
Do the conversion at the source DB, ETL tool, or API
Keeps Qlik lean and avoids re-computing on every app reload.
• For a fixed zone, add or subtract hours / 24.• For regions with daylight changes, use ConvertToLocalTime() or adjust before the data hits Qlik.
That's all for this post. Time is certainly tricky, but once you understand Qlik’s dual-value modeland leverage the tips and tricks above, it becomes just another dimension in your analytics!
Thanks for reading!
...View More
Tired of boring, static KPIs? Learn how to layer charts and metrics using Qlik’s layout container to create dynamic, composite KPIs. Bring your dashboards to life with trends, context, and impact—all in one view on the next episode of Do More with Qlik - Tips and Tricks.
In this episode of Do More with Qlik: Tips and Tricks Edition, I walk you through how to createdependent task chains in Qlik Cloud. Whether you're managing scripts, data flows, or apps, building a task chain ensures that each process runs in sequence—only when the previous one succeeds.
We’ll be working in a demo space called “Tasks Demo,” using three core objects:
A script that pulls pricing data and stores it in cloud storage.
A data flow that combines that data with inventory details to create a QVD.
An app that visualizes the results in a clear and simple dashboard.
In this video, you’ll learn how to:
Set up a scheduled time-based task.
Configure tasks to trigger only when a prior task succeeds.
Monitor task progress and view refresh statuses in real time.
This approach not only improves the reliability of your data updates but also helps you build a foundation for more complex automation across your Qlik environment.
👇 Watch the video below to see the full walkthrough and learn how to build your own dependent task chain in just a few clicks.
Have questions? Drop them in the comments where the video is posted—I'm here to help!
Resources:
More Do More with Qlik Videos
Qlik Help - Scheduling Data Refreshes
...View More
Custom CSS has been a popular workaround in Qlik Sense for years, helping developers tweak layouts, hide buttons, and get around styling limitations. But things are shifting. With the Multi-KPI object being deprecated and native styling options getting stronger with every release, it’s a good time to rethink how we approach custom styling in Qlik Sense moving forward.
In this post, we’ll break down:
Why custom CSS is used in Qlik Sense
What’s changing (and why Multi-KPI is being deprecated)
Best practices for styling moving forward
Alternatives for injecting CSS when needed
What you can (and should) do now to future-proof your apps
Let’s dive in!
Why is custom CSS used in Qlik Sense?
In the past, Qlik’s built-in styling options were limited. That led to many developers using CSS to:
Hide toolbars, buttons, and headers
Apply custom fonts or background gradients
Create grouped layouts or dashboards with unique branding
Most of this was made possible by either creating custom themes, building extensions, or using the Multi-KPI object as a helper to inject CSS code. But as powerful as these techniques were, they also came with downsides, like breakage after updates or difficulty governing app behavior at scale.
So, What’s Changing?
The biggest shift is the deprecation of the Multi-KPI object, which has served as a popular CSS injection tool. Here's what you need to know:
EOL of the Multi-KPI object is May 2026:
Existing dashboards will still work for now, but migration is highly encouraged.
The object is deprecated due to governance challenges and unintended side effects from injected CSS.
If you’ve been using the Multi-KPI as a styling workaround, it’s time to plan for alternatives.
Native Styling Has Come a Long Way
Before reaching for CSS, it's worth exploring what Qlik now offers natively. Many of the styling tweaks that once required CSS are now fully supported in the product UI.
Here’s a quick look at recent additions:
Native styling available now or coming in the next update
Straight Table
Background images, word wrap, mini charts, zebra striping, null styling, header toggle
Pivot Table
Indentation mode, expand/collapse, RTL support, cyclic dimensions
Text Object
Bullet lists, hover toggle, border control, support for up to 100 measures
Line Chart
Point and line annotations
Scatter Plot
Reference lines with slope, customizable outline color and width
Layout Container
Object resizing and custom tooltips
Navigation Menu
Sheet title expressions, left/right panel toggle, divider control
And this list keeps growing. If you're building new apps or redesigning old ones, these built-in features will cover a huge percentage of use cases.
Many deprecated CSS tricks are now native. Check out the full Obsolete CSS Modifications post for examples and native replacements.
What About Themes?
Themes are not going anywhere. In fact, they remain the most robust and supported way to apply consistent styling across your app portfolio.
With custom themes, you can:
Define global font families, sizes, and colors
Style specific object types like bar charts, pie charts, list boxes, and even treemaps
Customize titles, footers, legends, and more via the JSON schema
Apply branding at scale without touching each sheet manually
You can still include CSS files in themes, but remember:
Inline styles used by Qlik objects may require the use of "!important" to override.
Themes are not ideal for object-ID-specific or user-interactive CSS injection.
If you're new to themes, Qlik.dev has a great guideto get started, or checkout my previous blog post for some tips and tricks.
Still Need Custom CSS? Here’s What You Can Do
If your use case goes beyond what native styling or themes can handle—like hiding a specific button, or styling based on object IDs—you still have a few options:
Extensions (with scoped CSS)Prefix styles with .qv-object-[extension-name] to isolate your rules.Load styles using RequireJS or inject via <style> in JS.?
MashupsFull control over styling via your own HTML + CSS + JavaScript.Ideal for web apps embedding Qlik charts via qlik-embed
What's Missing
A lot of Qlik users have voiced the same thing: "we still need an officially supported way to inject CSS at the sheet or app level"
Some have suggested:
A new “Advanced Styling” section in sheet properties.
A standalone helper object just for advanced styling (like Multi-KPI but cleaner).
Ability to define per-object-type styling rules in themes (e.g. “all straight tables”).
Qlik has acknowledged this feedback and hinted that future solutions are being considered.
What You Should Do Today
Use native styling wherever possible—it's safer, easier to maintain, and now way more powerful
Migrate away from Multi-KPI if you’ve been using it to inject CSS
Explore themes for app-wide branding and consistent object styling
Use extensions or mashups for truly custom experiences
Follow community updates for new announcements around styling capabilities
That’s a wrap on this post. With more native styling features on the way, I’ll be keeping an eye out and will be likely sharing a follow-up as things evolve. If you're in the middle of refactoring or exploring new approaches, stay tuned, there’s more to come.
...View More
Qlik's Mike Tarallo details his personal experience with HVAC issues and how he utilized Qlik Answers to resolve a costly and complicated situation involving mismatched air conditioning units.
Last week a new presentation option for the bar chart was introduced in Qlik Cloud. The Butterfly presentation format displays two measures that mirror one another along the axis based on a single dimension. In the past, there have been methods used to generate the butterfly chart but now, it is a property option in the bar chart. Below are examples of butterfly charts. In the first example,the butterfly chart is comparing the average salary for men and women by country. In the second example, game stats are being compared for two selected college basketball teams.
Human Capital Management
Bracket Mania
Let’s look at how easy it is to create a butterfly chart. In the Human Capital Management example, the butterfly chart is comparing the average salary for men and women by country. The butterfly chart requires one dimension and two measures. In this example, Country is the dimension, and the two measures are as follows:
One measure for women and one measure for men. Both measures in a butterfly chart must return positive values to be displayed. If you are like me and used the old trick of creating butterfly charts by making one of the measures negative, you can simply remove that part of the expression to update your chart. In the app, both measures are master items, and a master color is applied to the measures so that males and females are different colors consistent with the rest of the app. Now, the only thing left to do is change the presentation to butterfly. This can be done from the properties of the bar chart in the Presentation > Styling section.
In both examples, the bar charts are horizontal, with mirroring measures on the y-axis. You also have the option to display the bar chart vertically. In this case, the mirroring measures will be on the x-axis.
Simple, right? As long as there are two items to be compared like male/female or team 1/team 2, a butterfly chart makes a nice alternative to the standard grouped or stacked bar chart. Try it for yourself and learn more at Qlik Help.
Jennell
...View More
I recently had an interesting use case for bookmarks that I thought I would share. I have a Qlik Sense app that will be accessed from more than one external source and the view of the app will differ depending on the referral link. In one scenario, the user is directed to the app overview of the app. In this scenario, no charts are highlighted. In the second scenario, the user is directed to a specific sheet in the app and a specific chart is highlighted. A message should also be displayed above the chart in this scenario. In this blog post, I will share an example of how this can be accomplished.
Here is a look at the original sheet:
And below is an example of the sheet with the top left chart highlighted. Notice that the chart is outlined and there is text above the chart. This is how the sheet should look in the second scenario when the user accesses the app via the bookmark URL.
To create the highlight for the chart, I added a layout container to the sheet. In the layout container, I added a text box for the highlight, a text box for the message and the chart I want to highlight. I made the background color of the first text object the color I wanted the highlight to be and positioned it behind the chart and a little larger than the chart (so that it appears like a border). I did not simply add a border to the chart because I want to control the show and hide of the highlight via a field value. The second text box has the message text and the same background color as the sheet.
I decided to use a field, _Message1, to control the show and hide of the highlight and the message. I added a table like the one below for this field.
I also use HidePrefix in the script before loading the table so that selections in this field do not appear in the selection bar.
I used the _Message1 field in the Show condition for the two text boxes (highlight and message) so that they were only visible when _Message1 = 1.
I also used the _Message1 field to change the bubble for the sales rep that I mentioned in the message. This can be done by using an expression to color the scatterplot bubbles.
Now, the only thing left to do is to create a bookmark that can be used to direct users to the Sales Analysis sheet and highlight the scatterplot. Before creating the bookmark, I went to the Sales Analysis sheet and selected 1 in the _Message1 field. Since I am hiding the _Message1 field, I made the selection in the browser URL by adding /select/_Message1/1 to the end URL while in analysis mode.
Now create a new bookmark and be sure to check ‘Save sheet location’ and ‘Save layout.’ To test the bookmark, clear selections in the selection bar and then select the bookmark. Don’t forget to make the bookmark public before publishing the app. Once the app is published, you can copy the link to the bookmark by going to bookmarks and clicking on the three dots next to the bookmark name and selecting Copy link. This bookmark link is what I used in an external source to direct users to the Sales Analysis sheet with the scatterplot highlighted. When I want to direct users to the app overview, I provided the URL to the app. The bookmark can also be used within the app, if necessary. If you do not want users to be able to clear the _Message1 field/remove the highlight and message, lock the field before creating the bookmark. This will prevent the _Message1 field from being cleared when the user clears all selections. To do this, you may need to temporarily remove the hideprefix in the script to lock the field.
If you would like to highlight a chart from within an app (and not an external source), consider using a button and the Go to chart action as seen in the May 2024 – Button Go to Chart sheet in the What’s New app. This allows you to add an action on a button that will not only direct you to a specific sheet but also to a chart that is temporarily highlighted.
This example illustrates how an app can have various views based on the referral URL. When accessing the URL to the app, the app is displayed without any chart highlights. Be sure to set the _Message1 field to 0 prior to publishing the app to ensure this. By using a bookmark URL, a message and highlighted chart is visible in the same app providing a different view for the user. This is just one of the many ways this can be accomplished in Qlik Sense.
Thanks,
Jennell
...View More