Solved Calculate time left

Discussion in 'Plugin Development' started by MaTaMoR_, Jan 29, 2015.

Thread Status:
Not open for further replies.
  1. Hi, how i can calculate the time left from two dates :S

    If i wanna know the time until "00:15:00" and now is "21:26:00" how i can calculate it ? i can't found a way to do it, may it is something stupid but i can't found a way to do it .

    PS: Is for deathban plugin .
     
  2. Offline

    1Rogue

    don't store the values like that, use a single value such as seconds or nanoseconds.
     
  3. Offline

    TGRHavoc

    For date related calculations (as stated in OP) look here.
    Otherwise, do what @1Rogue stated. Something like:
    Code:
    long startTime = System.nanoTime();
    // do something you want to measure e.g. Massive calculation
    long elapsedTimeNs = System.nanoTime() - startTime;
    Should suffice.
     
  4. :( It take almost 1 hour creating my SUPA system :(
    Show Spoiler

    Code:java
    1.  
    2. //---------------------- BAN DURATION ----------------------\\
    3. //Get full date
    4. String[] fulldate = getDate().split("-");
    5. Integer year = Integer.valueOf(fulldate[2]);
    6. Integer month = Integer.valueOf(fulldate[1]);
    7. Integer day = Integer.valueOf(fulldate[0]);
    8. //Get full hollur
    9. String[] fullhour = getHour().split(":");
    10. Integer hour = Integer.valueOf(fullhour[0]);
    11. Integer minute = Integer.valueOf(fullhour[1]);
    12. Integer second = Integer.valueOf(fullhour[2]);
    13.  
    14.  
    15. Integer duration = getRealTime(uuid);
    16.  
    17. Integer hours = 0;
    18. Integer minutes = duration % 60;
    19.  
    20. if((duration / 60) > 0) { hours = duration / 60; }
    21.  
    22. //---------------- CHECK HOURS ----------------\\
    23. //If the new hour is higher than 24
    24. if(hour + hours >= 24) {
    25. //Check if the new day is higher than the days of the month
    26. if(day + 1 > getDaysFromMonth(month)) {
    27. //Check if the new month is higher than 12
    28. if(month + 1 > 12) {
    29. year = year + 1;
    30. month = 1;
    31. day = 1;
    32. hour = 00;
    33. } else {
    34. //If the new month isn't higher than 12
    35. month = month + 1;
    36. day = 1;
    37. hour = 00;
    38. }
    39. } else {
    40. //If the new day isn't higher than the days of the month
    41. day = day + 1;
    42. hour = 00;
    43. }
    44. //If the new hour isn't higher than 24
    45. } else {
    46. hour = hour + hours;
    47. }
    48. //---------------- CHECK MINUTES ----------------\\
    49. //If the new minute is higher than 60
    50. if(minute + minutes > 60) {
    51. //If the new hour is higher than 24
    52. if(hour + 1 >= 24) {
    53. //If the new day is higher than the days of the month
    54. if(day + 1 > getDaysFromMonth(month)) {
    55. //If the new month is higher than 12
    56. if(month + 1 > 12) {
    57. year = year + 1;
    58. month = 1;
    59. day = 1;
    60. hour = 00;
    61. minute = (minutes + minute) - 60;
    62. } else {
    63. //If the new month isn't higher than 12
    64. month = month + 1;
    65. day = 1;
    66. hour = 00;
    67. minute = (minutes + minute) - 60;
    68. }
    69. } else {
    70. //If the new day isn't higher than the days of the month
    71. day = day + 1;
    72. hour = 00;
    73. minute = (minutes + minute) - 60;
    74. }
    75. } else {
    76. //If the new hour isn't higher than 24
    77. hour = hour + 1;
    78. minute = (minutes + minute) - 60;
    79. }
    80. } else {
    81. //If the new minute isn't higher than 60
    82. minute = minute + minutes;
    83. }
    84. //A part of the code
    85.  


    And how it exactly works :confused: i mean with this system i can get until when the player will be banned
     
  5. Offline

    1Rogue

    What about days? Scaling? What if I pass in "999:42:-1"?
     
  6. My code can handle that .

    The thing is how i can get the milliseconds from until when the player will be banned .

    PS: My code only accept hours and minutes for what i use it works perfect.
     
    Last edited: Jan 29, 2015
  7. Offline

    TGRHavoc

    This link teaches/shows you how to do the calculations you want. It also gives you a way to parse dates making sure that you get notified about any errors in said date (Why re-invent the wheel and whatnot).

    Edit: In case you cannot view that link:
    Code:
    import java.text.SimpleDateFormat;
    import java.util.Date;
    public class DateDifferentExample {
        public static void main(String[] args) {
            String dateStart = "01/14/2012 09:29:58";
            String dateStop = "01/15/2012 10:31:48";
            //HH converts hour in 24 hours format (0-23), day calculation
            SimpleDateFormat format = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss");
            Date d1 = null;
            Date d2 = null;
            try {
                d1 = format.parse(dateStart);
                d2 = format.parse(dateStop);
                //in milliseconds
                long diff = d2.getTime() - d1.getTime();
                long diffSeconds = diff / 1000 % 60;
                long diffMinutes = diff / (60 * 1000) % 60;
                long diffHours = diff / (60 * 60 * 1000) % 24;
                long diffDays = diff / (24 * 60 * 60 * 1000);
                System.out.print(diffDays + " days, ");
                System.out.print(diffHours + " hours, ");
                System.out.print(diffMinutes + " minutes, ");
                System.out.print(diffSeconds + " seconds.");
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
     
    MaTaMoR_ likes this.
  8. That help a lot :) I have to re-code almost all but it will be worth.
     
  9. Offline

    TGRHavoc

    Glad you found it useful.
     
  10. Offline

    1Rogue

    That's the whole reason people usually define type arguments for time in those commands, e.g.:

    Code:java
    1. //Map string arguments to units
    2. private final Map<String, TimeUnit> units = new TreeMap<>(String.CASE_INSENSITIVE_ORDER) {{
    3. put("d", TimeUnit.DAYS);
    4. put("m", TimeUnit.MINUTES);
    5. put("s", TimeUnit.SECONDS);
    6. put("ms", TimeUnit.MILLISECONDS);
    7. //etc
    8. }}
    9.  
    10. /**
    11.  * Converts a supplied time and time argument to nanoseconds
    12.  *
    13.  * @param time the time to convert
    14.  * @param arg The string representing the time's unit of measure
    15.  * @return The time in nanoseconds
    16.  */
    17. public long convertToNanos(int time, String arg) {
    18. TimeUnit unit = units.get(arg);
    19. if (unit == null) {
    20. throw new IllegalArgumentException("Bad argument supplied!");
    21. }
    22. return unit.toNanos(time);
    23. }
    24.  
    25. //Convert nanoseconds to another time
    26. TimeUnit.NANOSECONDS.toMinutes(myTimeNS);


    Additionally I have an entire time api for this:
    Code:java
    1. long durationNS = /* your nanosecond timing */;
    2. sender.sendMessage(TimeUnit.formatTime(durationNS, TimeUnit.SECONDS)); //Sends time in a format such as "1 hour, 13 minutes", with TimeUnit.SECONDS as the minimum unit of time

    https://github.com/CodeLanx/Codelan...a/com/codelanx/codelanxlib/util/TimeUtil.java
     
    Experminator likes this.
  11. The only thing i didnt see is ¿ how i can know the time left until a date ?
    bandate - actualdate ?
     
    Last edited: Jan 30, 2015
  12. Offline

    1Rogue

    Yup! You need to make sure they're in the same unit of time when doing that though (which is why I typically stick to the standard of keeping time in nanoseconds).
     
  13. I did read that api and i did see you have something for Scoreboard, what does it ? :confused:

    PS : That commandhandler looks good, you have any example of how to use it .
     
  14. Offline

    Experminator

    @1Rogue What does TreeMap?

    @1Rogue Goodwork to anti-copy :D
    They cant use:
    Code:
    long durationNS = /* your nanosecond timing */;
    
    It gives a error :D

    I like that anti-copy way :D

    EDIT by Timtower: merged posts
     
    Last edited by a moderator: Jan 30, 2015
    ChipDev likes this.
  15. Offline

    ChipDev

    Well,.. *cough* you can't tell them that *cough*
     
  16. Offline

    Experminator

  17. Offline

    FerusGrim

    Using System#nanoTime is a waste of resources. Unless, for some reason, you need an extremely precise measurement of time from within the same method, at least.

    But, considering this is a "calculate time left" type plugin, the calculation is being done over a period of time. Meaning that the smallest increment in time that you can deal with is a 20th of a second, because that's what the server 'ticks' at.

    Given that System#currentTimeMillis works at a 1000th of a second, using System#nanoTime is a considerable waste.

    @MaTaMoR_ @TGRHavoc
     
    Experminator likes this.
  18. Offline

    Experminator

  19. How it works ? :S
    Code:java
    1.  
    2. long durationNS = false; //Maybe this ?
    3.  


    Show Spoiler

    sarcasm
     
    Last edited: Jan 30, 2015
  20. Offline

    Experminator

    @MaTaMoR_ A long can't be false...... (It can only if Java 'false' translate to 0.)
     
  21. Offline

    TGRHavoc

    Apparently, using System.nanoTime on Windows is less efficient than the System.currentTimeMillis.
    So, yes in respect to the Windows OS, System.nanoTime is less efficient.

    However, on Linux (OS that most servers use), nanoTime is faster than currentTimeMillis and is certainly faster than it is on Windows.

    EDIT:

    Please, learn Java before attempting to use the Bukkit API. There are a lot of great resources that you can utilize to help you learn this programming language.
     
  22. Offline

    FerusGrim

    @TGRHavoc

    Re-read my post, Havoc. I hate repeating myself.
     
  23. Offline

    Experminator

    @TGRHavoc Is there a way that is fast on both platforms?

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: Jun 13, 2016
  24. So i have to change falso to true ?
     
  25. Offline

    FerusGrim

    @TGRHavoc @MaTaMoR_

    I feel the need to explain, anyways.

    The OP is attempting to periodically check if a player is banned.

    Now, efficiency dictates that the time does not need to be accurate, but rather the minimum processing of time. In the case of a Bukkit server, this is 20 times per second.

    Now, what does this mean? Well, lets look at the time calculations. We don't care about the time being accurate, we care about the tick being accurate.

    A millisecond is 1,000 seconds.
    A nanosecond is 1,000,000,000 seconds.

    Now, lets say we have 200ms left before the ban wears off. That means we have 100 * 1,000,000 nanoseconds left before the ban wears off. The next tick, no matter which calculation you're using, the player will still be banned.

    Okay, so let's say that we have 40ms before the ban wears off, and 40,000,000 nanoseconds left. The next tick, no matter which calculation you're using, the player will be unbanned.

    Both milliseconds and nanoseconds function above the tick base. Meaning that while milliseconds are 1000 per second and nanoseconds are 1000000000 per second, the tick is only 20 per second.

    Meaning that no matter how accurate you want to be, the tick will not change. You'll get the same result, no matter nano or millisecond. So using a nanosecond which is 1,000,000 times larger than a millisecond, is a complete waste of resources.
     
  26. Offline

    mythbusterma

    @Experminator

    Yes, System.currentTimeMillis() is much much much much faster than any Bukkit plugin will ever care about. It will legitimately have zero noticeable effect on your application's runtime.

    Does that make sense?
     
  27. Offline

    Experminator

  28. Offline

    1Rogue

    Noooooot quite.

    Yes, typically on most systems nanoTime will be outperformed by a different time check (such as currentTimeMillis), however in any kind of time-tracking, you want to have the most precise measure possible without a performance drawback that causes time checking overlaps. The way nanoTime works will return you the correct time upon the call of the method, but unless you are checking nanotime in a loop repeatedly, then you usually do not run into an overlap.

    Just because the server uses "ticks" for updating entities and other game data, doesn't mean that the JVM runs on ticks in a similar fashion. This is another reason why if you have time-critical tasks you shouldn't use bukkit's scheduler but your own ExecutorService in order to operate on a basis of realtime instead of the variable time that is ticks (usually 1/20th of a second, but can change).

    Which leads me to:

    Unless I'm misreading, you're implying that a tick is always 1/20th of a second. If your server is under strain and begins to run slower (say, 15 ticks per second), then when you are considering ticks to be 20tps, you might turn a measure of a second into 1.33 seconds in reality (which if you scale, could mean a 30 day ban becomes a 40 day ban, if we assume a constant 15tps).

    The other aspect of nanotime that I didn't really bring up here is portability, where almost all sql schema have built-in measures/operations for nanoseconds but not milliseconds.
     
  29. Offline

    Experminator

    @1Rogue Wait but that means when a player be temporary banned for like 10 days, and then the server has instant lagg with 15 tps, they are banned for 20 days.. But when the lagg is over, they banned for 10 days?
     
  30. Offline

    1Rogue

    Not quite. It would fluctuate the amount of time that has passed compared to realtime. So if someone has waited for 2 days for their ban to be gone, it might actually be 1.65 days according to the server.
     
Thread Status:
Not open for further replies.

Share This Page