Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / Java

Converting Between Dates and Pixels

4.93/5 (5 votes)
8 Nov 2013LGPL32 min read 15.5K   336  
Teaches how to write a simple class to convert dates to pixel X values and back.

Steelray Gantt Chart

Introduction

This article teaches you how to write a simple class to convert dates to values on an X-axis and vice versa. This is one of the most fundamental calculations in rendering a Gantt chart for project management software. We use this class in our viewer for Microsoft Project (see image above), but it could be applied in many other ways as well.

Background

It will help to understand the basic math behind the calculations. First, a couple of conventions. The algorithm will work for any kind of units, but we'll call our units pixels in this article. Second, we've picked days as our unit of time measure, but depending on your needs, other units (seconds, days, etc.) would work just as well.

To convert a date to a point on an X axis, we need to know a few things:

  • D: the date to convert
  • S: the date at the start (leftmost point) of the X axis
  • W: width (in pixels) of a day

With these three pieces of information, the X value can be calculated with a simple formula:

X = (D - S) * W

To convert a point to a date, we simply solve the above equation for D:

D = (X / W) + S

Using the code

The class will need to keep track of S and W, the start date and the day width from our formulas above. We also keep a constant to convert milliseconds to days.

Java
private Date start = null;
private double dayWidth = 0;
private double lengthOfDayInMs = 86400000f;

To instantiate and initialize the class, provide a constructor with S and W:

Java
// Constructor
// start - start date
// width - how wide (in units) a day is.
public PointConverter(Date start, float width) {
    this.dayWidth = width;
    this.start = start;
}

The conversion functions use our formulas from above (with some conversion to/from days to make sure the units are uniform).

Java
// dateToPoint - convert Date d to an X value
public float dateToPoint(Date d) {
    // Compute how many days since the start
    long elapsed = d.getTime() - start.getTime();
    double daysPast = ((float)(elapsed / lengthOfDayInMs));
    
    // return the X value        
    return ((float)(daysPast * dayWidth));
}

// pointToDate - convert an X value to a date
public Date pointToDate(float x) {
    // The formula is the reverse of dateToPoint
    long elapsed = start.getTime() + ((long)((x / dayWidth) * lengthOfDayInMs));
    return new Date(elapsed);
}

This class works fine if the starting date or scale never changed, but in a Gantt chart, those two values change quite frequently. To accomodate that reality, we provide an update method to allow the start date and day width to change:

Java
// update - pass new values in for start and width
public void update(Date start, float width) {
    this.start = start;
    dayWidth = width;
}

History

This is the initial version of the article/code.

License

This article, along with any associated source code and files, is licensed under The GNU Lesser General Public License (LGPLv3)