-3

Basically im trying to make a countdown timer to specific date, but i dont want the output to be a standard yy/mm/dd/ss format, i want it to display the number of years and the a decimal percentage, like so : 16.39872937498273 years left until blah.. and so far i have created a system clock that updates as far as milliseconds but no further..

so how to get a date to convert to year + decimal and how do you update a clock farther than milliseconds?

so far this is my code, only counts up and displays system time, i need to change it to count down and to a date.

import javax.swing.*;
import javax.swing.Timer;

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.*;

public class Base extends JFrame{

     private JPanel p1;
     private JLabel time;

public static void main(String[] args){
    Base myFrame = new Base();
    myFrame.pack();
    myFrame.setTitle("Digital Clock");
    myFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    myFrame.setLocationRelativeTo(null);
    myFrame.setVisible(true);


}//main()

public Base(){
System.out.println(currentTime());
JPanel p1 = new JPanel();
p1.setLayout(new FlowLayout());
JLabel time = new JLabel(currentTime());
time.setFont(new Font("Gulim", Font.BOLD, 20));
time.setForeground(Color.blue);
p1.add(time);
this.setLayout(new BorderLayout());
this.add(p1, BorderLayout.CENTER);
ActionListener taskPerformer = new ActionListener() {
    public void actionPerformed(ActionEvent evt) {
        System.out.println(currentTime());
        time.setText(currentTime());
    }
};
Timer t = new Timer(50, taskPerformer);
t.start();
}

public String currentTime(){
    DateFormat df = new SimpleDateFormat("MM/dd/yy hh:mm:ssSSS");
    Date dateobj = new Date();
   String currentTime = df.format(dateobj);
   return currentTime;
 }

public String checkTime(int t){
    String time1;
    if (t < 10){
        time1 = ("0"+t);
        }
    else{
        time1 = (""+t);
        }
    return time1;
}

public String amP(int ap){
    String amPm;
    if( ap == 0)
        amPm = "AM";
    else
        amPm = "PM";
    return amPm;
}

}
Ricky B
  • 3
  • 1

3 Answers3

0

My solution is to solve it straight,you can calculate the days and hours into seconds,compared to the year,as the following shows,change the code:

public String currentTime(){
   DateFormat df = new SimpleDateFormat("MM/dd/yy hh:mm:ssSSS");
   Date dateobj = new Date();
   String currentTime = df.format(dateobj);
   return currentTime;
}

to :

public String currentTime(){
   double year = Calendar.getInstance().get(Calendar.YEAR);
   double day_in_year = Calendar.getInstance().get(Calendar.DAY_OF_YEAR);
   double nanoTime0=System.nanoTime()/(1000000000);
   double nanoTime1=nanoTime0/(3600*12*365);
   double cTime=year+day_in_year/365+nanoTime1;
   String currentTime=new BigDecimal(cTime).toPlainString();
   return currentTime;
}

the output is:

...

2016.9509955606290532159619033336639404296875 2016.9509955606290532159619033336639404296875 2016.9509955606290532159619033336639404296875 2016.9509955606290532159619033336639404296875 2016.9509955606290532159619033336639404296875 2016.9509955606290532159619033336639404296875 2016.9509955606290532159619033336639404296875 2016.9509955606290532159619033336639404296875 2016.95099562404857351793907582759857177734375 2016.95099562404857351793907582759857177734375 2016.95099562404857351793907582759857177734375 2016.95099562404857351793907582759857177734375 2016.95099562404857351793907582759857177734375 2016.95099562404857351793907582759857177734375 2016.95099562404857351793907582759857177734375 ...

Notice:because the nanoTime() method create the small digits which are too samll to be recognized by the compiler,there are some samee time in the output.

Waiting for a better solution.

doctorrm
  • 13
  • 7
0

Avoid legacy date-time classes

You are using old date-time classes that have proven to be troublesome, confusing, and flawed.

The old Calendar and Date classes are now legacy. Supplanted by the java.time classes.

java.time

Use the java.time classes for date-time work.

Caveat: I do not recommend representing a span of time as a decimal number. Counting a span of time as something like “1.062 years later” has no utility that I know of. Instead I suggest using the standard ISO 8601 format for a textual representation (PnYnMnDTnHnMnS). Nevertheless, I took on this Question as a puzzle challenge.

To obtain a decimal fraction representing a fraction of the year, use the Period and Duration classes, with Year helping out. The strategy is to get a fraction of year and determine the length of that fractional year in nanoseconds. Divide that number by the number of nanoseconds in that particular year (years vary in length by Leap Year and by anomalies such as redefinition of time zone), to get our decimal fraction. Add the total number of whole years for a result.

Determine the start and stop of our span of time.

ZoneId z = ZoneId.of ( "America/Montreal" );
ZonedDateTime zdtStart = ZonedDateTime.of ( 2015 , 2 , 21 , 12 , 34 , 56 , 0 , z );
ZonedDateTime zdtStop = ZonedDateTime.of ( 2016 , 3 , 15 , 12 , 34 , 56 , 0 , z );

Get the count of whole years via Period.

Period p = Period.between ( zdtStart.toLocalDate () , zdtStop.toLocalDate () );
int years = p.getYears ();

Now focus on the fraction of a year. Add the number of whole years to the starting moment to get the start of that last fractional year.

ZonedDateTime zdtStartFractional = zdtStart.plusYears ( years );

Get the span of time, unattached from timeline, between our start of fractional year and the stopping point of our original span.

Duration fractionalYear = Duration.between ( zdtStartFractional , zdtStop );

Calculate our divisor, the length of this particular year in nanoseconds. Get the moment the year starts, and get a year later when following year starts.

ZonedDateTime zdtFractionalYear_StartOfYear = zdtStartFractional.with ( TemporalAdjusters.firstDayOfYear () ).toLocalDate ().atStartOfDay ( z );
Duration wholeYear = Duration.between ( zdtFractionalYear_StartOfYear , zdtFractionalYearStart.plusYears ( 1 ) );

Get the nanoseconds. To avoid the extraneous extra digits of floating point technology, we avoid float/Float and double/Double, using BigDecimal for accuracy. Specify the scale (number of decimal fraction digits) you want in your result; here we use 32 arbitrarily.

BigDecimal fractionalYearAsNanos = new BigDecimal ( fractionalYear.toNanos () );
BigDecimal wholeYearAsNanos = new BigDecimal ( wholeYear.toNanos () );
BigDecimal ratio = fractionalYearAsNanos.divide ( wholeYearAsNanos , 32 , RoundingMode.HALF_EVEN );
BigDecimal result = ratio.add ( new BigDecimal ( years ) );

Dump to console.

System.out.println ( zdtStart + "/" + zdtStop );
System.out.println ( "Years: " + result.toPlainString () );

2015-02-21T12:34:56-05:00[America/Montreal]/2016-03-15T12:34:56-04:00[America/Montreal]

Years: 1.06272768670309653916211293260474

See live code in IdeOne.com.


About java.time

The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.

The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.

To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.

Where to obtain the java.time classes?

  • Java SE 8 and SE 9 and later
    • Built-in.
    • Part of the standard Java API with a bundled implementation.
    • Java 9 adds some minor features and fixes.
  • Java SE 6 and SE 7
    • Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
  • Android

The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.

Community
  • 1
  • 1
Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154
-2

You can use System.nanoTime() to go beyond milliseconds, and then you can use your logic to calculate the years in the desired format.

bibhu_bioit
  • 97
  • 1
  • 9
  • Incorrect. The class doc explains that `nanoTime` method is for capturing elapsed time. Has nothing to do with current time nor with dates. – Basil Bourque Dec 12 '16 at 14:36