48

What i am trying to do::

Show message based on

  • Good morning (12am-12pm)
  • Good after noon (12pm -4pm)
  • Good evening (4pm to 9pm)
  • Good night ( 9pm to 6am)

CODE::

I used 24-hr format to get this logic

private void getTimeFromAndroid() {
        Date dt = new Date();
        int hours = dt.getHours();
        int min = dt.getMinutes();

        if(hours>=1 || hours<=12){
            Toast.makeText(this, "Good Morning", Toast.LENGTH_SHORT).show();
        }else if(hours>=12 || hours<=16){
            Toast.makeText(this, "Good Afternoon", Toast.LENGTH_SHORT).show();
        }else if(hours>=16 || hours<=21){
            Toast.makeText(this, "Good Evening", Toast.LENGTH_SHORT).show();
        }else if(hours>=21 || hours<=24){
            Toast.makeText(this, "Good Night", Toast.LENGTH_SHORT).show();
        }
    }

Question:

  • Is this this best way of doing it, If no which is the best way
Devrath
  • 39,949
  • 51
  • 178
  • 266
  • @Devrath off-topic note, should'nt it be AND && , you are using OR || which will result all cases (hours >= 1) fall in Good Morning case? – Yazan Dec 21 '14 at 13:16
  • You should know, that the hours are in range between `0` and `23`: [`getHours()`](http://docs.oracle.com/javase/6/docs/api/java/util/Date.html#getHours%28%29). – Tom Dec 21 '14 at 13:54
  • @Devrath I've updated the answer to take into account 12:59. – user987339 Dec 21 '14 at 14:07
  • 1
    FYI, the troublesome date-time classes such as `java.util.Date`, `java.util.Calendar`, and `java.text.SimpleDateFormat` are now legacy, supplanted by the [*java.time*](https://docs.oracle.com/javase/10/docs/api/java/time/package-summary.html) classes. Most of the *java.time* functionality is back-ported to Java 6 & Java 7 in the [***ThreeTen-Backport***](http://www.threeten.org/threetenbp/) project. Further adapted for earlier Android (<26) in [***ThreeTenABP***](https://github.com/JakeWharton/ThreeTenABP). See [*How to use ThreeTenABP…*](http://stackoverflow.com/q/38922754/642706). – Basil Bourque Jun 12 '19 at 03:57

17 Answers17

98

You should be doing something like:

Calendar c = Calendar.getInstance();
int timeOfDay = c.get(Calendar.HOUR_OF_DAY);

if(timeOfDay >= 0 && timeOfDay < 12){
    Toast.makeText(this, "Good Morning", Toast.LENGTH_SHORT).show();        
}else if(timeOfDay >= 12 && timeOfDay < 16){
    Toast.makeText(this, "Good Afternoon", Toast.LENGTH_SHORT).show();
}else if(timeOfDay >= 16 && timeOfDay < 21){
    Toast.makeText(this, "Good Evening", Toast.LENGTH_SHORT).show();
}else if(timeOfDay >= 21 && timeOfDay < 24){
    Toast.makeText(this, "Good Night", Toast.LENGTH_SHORT).show();
}
Vrutin Rathod
  • 873
  • 1
  • 11
  • 16
SMA
  • 35,277
  • 7
  • 46
  • 71
  • 3
    I would add an `else` case at the bottom to catch any unexpected value ([defensive programming](http://en.m.wikipedia.org/wiki/Defensive_programming)). – Basil Bourque Dec 21 '14 at 18:49
  • @BasilBourque Exactly. Even if it notifies your support team of a strange edge case. The key is to not let this crash the app since it's not mission critical. – Joshua Pinter May 13 '17 at 19:52
  • getInstance(); need android api 24. – Abed Putra Aug 04 '17 at 15:40
  • FYI, the troublesome date-time classes such as `java.util.Date`, `java.util.Calendar`, and `java.text.SimpleDateFormat` are now legacy, supplanted by the [*java.time*](https://docs.oracle.com/javase/10/docs/api/java/time/package-summary.html) classes. Most of the *java.time* functionality is back-ported to Java 6 & Java 7 in the [***ThreeTen-Backport***](http://www.threeten.org/threetenbp/) project. Further adapted for earlier Android (<26) in [***ThreeTenABP***](https://github.com/JakeWharton/ThreeTenABP). See [*How to use ThreeTenABP…*](http://stackoverflow.com/q/38922754/642706). – Basil Bourque Jun 12 '19 at 03:58
24

For anyone who is looking for the latest Kotlin syntax for @SMA's answer, here is the helper function :

fun getGreetingMessage():String{
    val c = Calendar.getInstance()
    val timeOfDay = c.get(Calendar.HOUR_OF_DAY)

    return when (timeOfDay) {
           in 0..11 -> "Good Morning"
           in 12..15 -> "Good Afternoon"
           in 16..20 -> "Good Evening"
           in 21..23 -> "Good Night"
           else -> "Hello"
      }
    }
user672009
  • 3,839
  • 6
  • 36
  • 68
Vishal Sonawane
  • 2,537
  • 2
  • 13
  • 21
7

I would shorten your if/elseif statement to:

String greeting = null;
if(hours>=1 && hours<=12){
    greeting = "Good Morning";
} else if(hours>=12 && hours<=16){
    greeting = "Good Afternoon";
} else if(hours>=16 && hours<=21){
    greeting = "Good Evening";
} else if(hours>=21 && hours<=24){
    greeting = "Good Night";
}
Toast.makeText(this, greeting, Toast.LENGTH_SHORT).show();
Tom
  • 15,514
  • 17
  • 42
  • 51
Konstantin Yovkov
  • 60,548
  • 8
  • 97
  • 143
5

java.time

I would advise to use Java 8 LocalTime.

Maybe create a class like this to handle your time of day problem.

public class GreetingMaker { // think of a better name then this.

  private static final LocalTime MORNING = LocalTime.of(0, 0, 0);
  private static final LocalTime AFTER_NOON = LocalTime.of(12, 0, 0);
  private static final LocalTime EVENING = LocalTime.of(16, 0, 0);
  private static final LocalTime NIGHT = LocalTime.of(21, 0, 0);

  private LocalTime now;

  public GreetingMaker(LocalTime now) {
    this.now = now;
  }

  public void printTimeOfDay() { // or return String in your case
    if (between(MORNING, AFTER_NOON)) {
      System.out.println("Good Morning");
    } else if (between(AFTER_NOON, EVENING)) {
      System.out.println("Good Afternoon");
    } else if (between(EVENING, NIGHT)) {
      System.out.println("Good Evening");
    } else {
      System.out.println("Good Night");
    }
  }

  private boolean between(LocalTime start, LocalTime end) {
    return (!now.isBefore(start)) && now.isBefore(end);
  }

}
Yoshua Nahar
  • 1,224
  • 11
  • 24
  • That first clause in your `between` test predicate should be `( ! now.isBefore( start ) )` to handle the moment when now *is* `start`. – Basil Bourque Sep 25 '17 at 06:17
  • Not sure if technically required, but I would put parens around that first clause to be safe and to be clear regarding the effect of the `NOT` “!”. – Basil Bourque Sep 26 '17 at 06:35
2

You determine if it is in the first interval, and then all other intervals depends on the upper limit. So you can make it even shorter:

String greeting = null;
if(hours>=1 && hours<=11){
    greeting = "Good Morning";
} else if(hours<=15){
    greeting = "Good Afternoon";
} else if(hours<=20){
    greeting = "Good Evening";
} else if(hours<=24){
    greeting = "Good Night";
}
Toast.makeText(this, greeting, Toast.LENGTH_SHORT).show();
user987339
  • 10,111
  • 8
  • 40
  • 43
  • Do you want at 12:59 a good morning or Good afternoon? You need to test @Devrath before accepting the answer. – SMA Dec 21 '14 at 13:57
  • @ almas shaikh .... can you edit your answer for optimization as `user987339` suggested ? ........ @ [+1] for `user987339` for optimization – Devrath Dec 21 '14 at 13:59
  • @ almas sheikh you were right. I've updated the answer for case of 12:59 – user987339 Dec 21 '14 at 14:06
  • Well, it is not nice, that I won't get any greeting if `hours` is `0`. – Tom Dec 21 '14 at 14:10
  • Please read this [JavaDoc](http://docs.oracle.com/javase/6/docs/api/java/util/Date.html#getHours%28%29). – Tom Dec 21 '14 at 14:16
2

try this code(get hours and get minute methods in Date class are deprecated.)

 private void getTimeFromAndroid() {
    Date dt = new Date();
    Calendar c = Calendar.getInstance();
    c.setTime(dt);
    int hours = c.get(Calendar.HOUR_OF_DAY);
    int min = c.get(Calendar.MINUTE);

    if(hours>=1 && hours<=12){
        Toast.makeText(this, "Good Morning", Toast.LENGTH_SHORT).show();
    }else if(hours>=12 && hours<=16){
        Toast.makeText(this, "Good Afternoon", Toast.LENGTH_SHORT).show();
    }else if(hours>=16 && hours<=21){
        Toast.makeText(this, "Good Evening", Toast.LENGTH_SHORT).show();
    }else if(hours>=21 && hours<=24){
        Toast.makeText(this, "Good Night", Toast.LENGTH_SHORT).show();
    }
}
Sagar G.
  • 494
  • 7
  • 15
m2k_72
  • 51
  • 5
2

Using Time4J (or Time4A on Android) enables following solutions which do not need any if-else-statements:

ChronoFormatter<PlainTime> parser =
    ChronoFormatter.ofTimePattern("hh:mm a", PatternType.CLDR, Locale.ENGLISH);
PlainTime time = parser.parse("10:05 AM");

Map<PlainTime, String> table = new HashMap<>();
table.put(PlainTime.of(1), "Good Morning");
table.put(PlainTime.of(12), "Good Afternoon");
table.put(PlainTime.of(16), "Good Evening");
table.put(PlainTime.of(21), "Good Night");
ChronoFormatter<PlainTime> customPrinter=
    ChronoFormatter
      .setUp(PlainTime.axis(), Locale.ENGLISH)
      .addDayPeriod(table)
      .build();
System.out.println(customPrinter.format(time)); // Good Morning

There is also another pattern-based way to let the locale decide in a standard way based on CLDR-data how to format the clock time:

ChronoFormatter<PlainTime> parser =
    ChronoFormatter.ofTimePattern("hh:mm a", PatternType.CLDR, Locale.ENGLISH);
PlainTime time = parser.parse("10:05 AM");

ChronoFormatter<PlainTime> printer1 =
    ChronoFormatter.ofTimePattern("hh:mm B", PatternType.CLDR, Locale.ENGLISH);
System.out.println(printer1.format(time)); // 10:05 in the morning

ChronoFormatter<PlainTime> printer2 =
    ChronoFormatter.ofTimePattern("B", PatternType.CLDR, Locale.ENGLISH)
        .with(Attributes.OUTPUT_CONTEXT, OutputContext.STANDALONE);
System.out.println(printer2.format(time)); // morning

The only other library known to me which can also do this (but in an awkward way) is ICU4J.

Meno Hochschild
  • 40,702
  • 7
  • 93
  • 118
1

You can equally have a class that returns the greetings.

import java.util.Calendar;

public class Greetings {
    public static String getGreetings()
    {
        Calendar c = Calendar.getInstance();
        int timeOfDay = c.get(Calendar.HOUR_OF_DAY);

        if(timeOfDay < 12){
            return "Good morning";
        }else if(timeOfDay < 16){
            return "Good afternoon";
        }else if(timeOfDay < 21){
            return "Good evening";
        }else {
            return "Good night";
        }
    }
}
Donnicias
  • 156
  • 6
  • 2
    FYI, the terribly flawed date-time classes such as [`java.util.Date`](https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/Date.html), [`java.util.Calendar`](https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/Calendar.html), and `java.text.SimpleDateFormat` are now [legacy](https://en.wikipedia.org/wiki/Legacy_system), supplanted by the [*java.time*](https://docs.oracle.com/javase/tutorial/datetime/TOC.html) classes built into Java 8 and later. – Basil Bourque Apr 02 '20 at 20:11
  • The removal of the greater than parts make this look very similar to the solution by Jianqing GAO. – Scratte Apr 02 '20 at 20:41
1

For Kotlin Users They can use it like this :

private fun showDayMessage():String {
    val c: Calendar = Calendar.getInstance()
    var message:String ?=null
    val timeOfDay: Int = c.get(Calendar.HOUR_OF_DAY)
    if (timeOfDay >= 0 && timeOfDay < 12) {
        message =  "Good Morning"
    } else if (timeOfDay >= 12 && timeOfDay < 16) {
        message =  "Good Afternoon"
    } else if (timeOfDay >= 16 && timeOfDay < 21) {
        message =  "Good Evening"
    } else if (timeOfDay >= 21 && timeOfDay < 24) {
        message =  "Good Night"
    }
    return  message!!
}
Nadeem Bhat
  • 1,012
  • 7
  • 10
0

When I write

Calendar c = Calendar.getInstance();
int timeOfDay = c.get(Calendar.HOUR_OF_DAY);

I didn't get output and it doesn't show any error. Just the timeOfDay won't get assigned any value in the code. I felt it was because of some threading while Calendar.getInstance() is executed. But when I collapsed the lines it worked for me. See the following code:

int timeOfDay = Calendar.getInstance().get(Calendar.HOUR_OF_DAY);

if(timeOfDay >= 0 && timeOfDay < 12){
        greeting.setText("Good Morning");
}else if(timeOfDay >= 12 && timeOfDay < 16){
        greeting.setText("Good Afternoon");
}else if(timeOfDay >= 16 && timeOfDay < 21){
        greeting.setText("Good Evening");
}else if(timeOfDay >= 21 && timeOfDay < 24){
        greeting.setText("Good Morning");
}
SREE
  • 456
  • 3
  • 19
0
 private String getStringFromMilli(long millis) {

    Calendar c = Calendar.getInstance();
    c.setTimeInMillis(millis);
    int hours = c.get(Calendar.HOUR_OF_DAY);

    if(hours >= 1 && hours <= 12){
        return "MORNING";
    }else if(hours >= 12 && hours <= 16){
        return "AFTERNOON";
    }else if(hours >= 16 && hours <= 21){
        return "EVENING";
    }else if(hours >= 21 && hours <= 24){
        return "NIGHT";
    }
    return null;
}
Sanjay Hadiya
  • 797
  • 8
  • 19
0

If somebody looking the same for Dart and Flutter: the code without if statements - easy to read and edit.

main() {
  int hourValue = DateTime.now().hour;
  print(checkDayPeriod(hourValue));
}

String checkDayPeriod(int hour) {
  int _res = 21;
  Map<int, String> dayPeriods = {
    0: 'Good night',
    12: 'Good morning',
    16: 'Good afternoon',
    21: 'Good evening',
  };

  dayPeriods.forEach(
    (key, value) {
      if (hour < key && key <= _res) _res = key;
    },
  );

  return dayPeriods[_res];
}
awaik
  • 7,222
  • 1
  • 34
  • 40
0
using System;

namespace PF_Claas_Assign1
{
    class Program
    {
        static void Main(string[] args)
        {
            DateTime Greeting = DateTime.Now;

            if (Greeting.Hour >= 5 && Greeting.Hour < 12)
            {
                Console.WriteLine("Good morning....!");
            }
            else if (Greeting.Hour >= 12 && Greeting.Hour < 16)
            {
                Console.WriteLine("Good afternoon...!");
            }
            else if (Greeting.Hour >= 16 && Greeting.Hour < 20)
            {
                Console.WriteLine("Good evening...!");
            }
            else
            {
                Console.WriteLine("Good night...!");
            }
        }
    }
}
Dmitriy Fialkovskiy
  • 2,845
  • 8
  • 29
  • 41
  • Why is this better than the other answers? Not to mention that it doesn't implement the times of the question. – RalfFriedl Oct 05 '19 at 09:48
  • 1
    Thanks for wanting to contribute. The question was tagged java, this means that a Java solution is asked for. Is yours C#? Also you’re not answering the question. It was: *Is this this best way of doing it? If no, which is the best way?* – Ole V.V. Oct 05 '19 at 13:01
0

In kotlin use the following

fun getCurrentTime(dateFormatInPut:String,myDate:String): Time {
        val sdf = SimpleDateFormat(dateFormatInPut, Locale.ENGLISH)
        val date = sdf.parse(myDate)
        val millis = date!!.time
        val calendar=Calendar.getInstance()
        calendar.timeInMillis=millis
        return when (calendar.get(Calendar.HOUR_OF_DAY)) {
            in 0..11 -> Time.Morning
            in 12..15 -> Time.AfterNoon
            else -> Time.Evening
        }

    }

Here Time is enum class

enum class Time {
Morning,
AfterNoon,
Evening

}

Roshan Kumar
  • 66
  • 1
  • 6
0

A cleaner method for detecting date would be.

//the time cannot go below zero, so if this case is true, it must be between 0 and 12
   if(time <= 12)
   {
       return "Good Morning";
       //it will only fall into this case if the time is greater than 12.
   }else if(time < 16)
   {
       return "Good Afternoon";
   }else if(time < 21)
   {
       return "Good Evening";
   }else //it is guaranteed that the time will not exceed 24
       //, and if the previous case are all false, it must be within 21 and 24
   {
       return "Good Night";
   }
0

As Simple as possible

 private String getTimeFromAndroid() {
            Date dt = new Date();
            Calendar c = Calendar.getInstance();
            c.setTime(dt);
            int hours = c.get(Calendar.HOUR_OF_DAY);
            int min = c.get(Calendar.MINUTE);
    
            if(hours<=12){       
                return "Good Morning";
            }else if(hours<=16){        
                return "Good Afternoon";        
            }else if(hours<=21){         
                return "Good Evening";        
            }else {
                return "Good Night";
            }              
        }
Mahmudul
  • 462
  • 1
  • 4
  • 11
  • It would be still simpler with `LocalTime` from [java.time, the modern Java date and time API](https://docs.oracle.com/javase/tutorial/datetime/). Your code is as old-fashioned as possible. – Ole V.V. Apr 09 '22 at 18:38
  • Also is there anything substantial here that isn’t already covered by the answers by donnicias and by Jianqing GAO? – Ole V.V. Apr 09 '22 at 18:52
-1

More specific

public static String getDayMessage() {
    Calendar c = Calendar.getInstance();
    int timeOfDay = c.get(Calendar.HOUR_OF_DAY);

    if (timeOfDay < 5) {
        return "Hi, Good Mid Night";
    }else if (timeOfDay < 6) {
        return "Hi, Good Late Night";
    } else if (timeOfDay < 12) {
        return "Hi, Good Morning";
    } else if (timeOfDay < 14) {
        return "Hi, Good Noon";
    } else if (timeOfDay < 16) {
        return "Hi, Good Afternoon";
    } else if (timeOfDay < 21) {
        return "Hi, Good Evening";
    } else {
        return "Hi, Good Night";
    }
}
  • 1
    Your approach has already been covered by Answers posted months ago. If yours is an improvement, edit to describe that improvement. If not, I suggest you delete the Answer. – Basil Bourque Nov 16 '20 at 00:30
  • 1
    This code uses the *terrible* `Calendar` class that was supplanted years ago by the modern *java.time* classes. See the [Answer](https://stackoverflow.com/a/46379428/642706) by Nahar. – Basil Bourque Nov 16 '20 at 00:32