Jesse G
Jesse G

Reputation: 538

How to set a custom time zone for Lightweight Charts?

I've got a lightweight chart setup that looks like this. I want to add some kind of configuration so that the chart can show me the local time as opposed to the universal time being passed by a Unix timestamp, which is a couple hours offset from mine for example. Another possibility is to modify the Unix timestamps.

var chart = LightweightCharts.createChart(document.getElementById("charts"), {
  width: 1060,
  height: 537,
  layout: {
    backgroundColor: "#161616",
    textColor: "rgba(255, 255, 255, 0.9)",
    fontSize: 15,
    fontFamily: "Ubuntu",
  },
  grid: {
    vertLines: {
      color: "#424242",
      width: 0.3,
    },
    horzLines: {
      color: "#424242",
      width: 0.3,
    },
  },
  crosshair: {
    mode: LightweightCharts.CrosshairMode.Normal,
  },
  priceScale: {
    borderColor: "rgba(197, 203, 206, 0.8)",
    size: 5,
  },
  timeScale: {
    borderColor: "rgba(197, 203, 206, 0.8)",
    timeVisible: true,
    secondsVisible: false,
    rightBarStaysOnScroll: true,
  },
});

Upvotes: 7

Views: 6283

Answers (3)

Daniel Garmoshka
Daniel Garmoshka

Reputation: 6352

I hope they will fix this soon, meanwhile if you don't want to distort original data, use following formatter:

const localTimezoneOffset = new Date().getTimezoneOffset() * 60

....

  timeScale: {
    timeVisible: true,
    tickMarkFormatter: (time, tickMarkType, locale) => {
      return defaultTickMarkFormatter({timestamp: time - localTimezoneOffset},
        tickMarkType, locale)
    },
  },

where defaultTickMarkFormatter is their default formatter:

function defaultTickMarkFormatter(timePoint, tickMarkType, locale) {
  const formatOptions = {};

  switch (tickMarkType) {
    case 0: //TickMarkType.Year:
      formatOptions.year = 'numeric';
      break;

    case 1: // TickMarkType.Month:
      formatOptions.month = 'short';
      break;

    case 2: //TickMarkType.DayOfMonth:
      formatOptions.day = 'numeric';
      break;

    case 3: //TickMarkType.Time:
      formatOptions.hour12 = false;
      formatOptions.hour = '2-digit';
      formatOptions.minute = '2-digit';
      break;

    case 4: //TickMarkType.TimeWithSeconds:
      formatOptions.hour12 = false;
      formatOptions.hour = '2-digit';
      formatOptions.minute = '2-digit';
      formatOptions.second = '2-digit';
      break;

    default:
      // ensureNever(tickMarkType);
  }

  const date = timePoint.businessDay === undefined
    ? new Date(timePoint.timestamp * 1000)
    : new Date(Date.UTC(timePoint.businessDay.year, timePoint.businessDay.month - 1, timePoint.businessDay.day));

  // from given date we should use only as UTC date or timestamp
  // but to format as locale date we can convert UTC date to local date
  const localDateFromUtc = new Date(
    date.getUTCFullYear(),
    date.getUTCMonth(),
    date.getUTCDate(),
    date.getUTCHours(),
    date.getUTCMinutes(),
    date.getUTCSeconds(),
    date.getUTCMilliseconds()
  );

  return localDateFromUtc.toLocaleString(locale, formatOptions);
}

Their documentation about timezones has a lot of sophistry (a sign that someone is sabotaging a simple task). They could easily add some property like convertToLocalTimezone: true or timezoneOffset: 7200, but it seems like they had an internal dispute and decided not to do anything. ☹️

vote for existing solutions or suggest new format to bring their attention to proper solution.

Upvotes: 1

Sourav Kumar
Sourav Kumar

Reputation: 11

There is one another way too.

Lightweight chart treats the unix timestamp as GMT time.

Example: To display the time as per IST (GMT+5:30), just add that number of seconds to the present time. (19800 seconds)

Upvotes: 1

timocov
timocov

Reputation: 1166

I've posted the similar question here, but didn't post an answer so far.

I see 2 approaches which might help you to solve this issue:

  1. You can modify source time of the bar by adding TZ offset to the time (which I think is preferred way - see below)
  2. You can override tickMarkFormatter, dateFormat and timeFormatter to format dates properly with desired TZ offset.

I think that the first way (with adding offset) is preferred because it'll also affect tick marks generation and their weight, so your timescale will look much better without issues (e.g. you can see 23:00 for time instead of 30 for day because you add an offset 60 min and it shifts timescale a bit).

EDIT (03.11.2021): Please this doc to get more information related to how to support time zones.

Upvotes: 7

Related Questions