Java 如何在Android Studio中为时间选择器设置正确的am/pm时间?

Java 如何在Android Studio中为时间选择器设置正确的am/pm时间?,java,android,datetime,timepicker,timezone-offset,Java,Android,Datetime,Timepicker,Timezone Offset,我试图根据一些样本城市及其各自的时区创建一个时间转换器。我以UTC为单位检索当前时间,然后根据每个时区UTC的偏移量加上或减去,然后加上或减去12,将时间转换为相应的12小时格式,因此可以是am或pm。然后,当用户从微调器中选择城市时,该信息将显示在计时器上 现在的问题是我得到了正确的时间,但对于某些时区,am\pm是向后的。例如,我的本地时间是美国东部时间,我想转换成太平洋标准时间。假设现在是晚上7点,我想知道洛杉矶的时间。它显示的不是下午4点,而是凌晨4点 所以我很难“纠正”时间。我用了一天

我试图根据一些样本城市及其各自的时区创建一个时间转换器。我以UTC为单位检索当前时间,然后根据每个时区UTC的偏移量加上或减去,然后加上或减去12,将时间转换为相应的12小时格式,因此可以是am或pm。然后,当用户从微调器中选择城市时,该信息将显示在计时器上

现在的问题是我得到了正确的时间,但对于某些时区,am\pm是向后的。例如,我的本地时间是美国东部时间,我想转换成太平洋标准时间。假设现在是晚上7点,我想知道洛杉矶的时间。它显示的不是下午4点,而是凌晨4点

所以我很难“纠正”时间。我用了一天中的.HOUR,我想这应该是夏令时的原因,我试着用HOUR,但这并不能解决问题,只能把时间推迟一个小时。 将24小时格式转换为12小时格式需要12小时的修正数学,但这并没有按照我的预期工作,因为正如我所提到的,虽然它设置为正确的小时,但它不能根据实际时间计算正确的am/pm。 此外,.setIs24HourView设置为false

无论如何,以下是处理此功能的函数:

public int convertTime(String city)
    {
        //Result of taking in the UTC time and adding/subtracting the offset
        int offset = 0;

        //gets the calender instance of time with GMT standard, then getting hour of day
        Calendar c = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
        int UTC = c.get(Calendar.HOUR_OF_DAY);

        //set offset according to city
        switch(city)
        {
            case "New York":
                offset = UTC-4;
                break;
            case "London":
                offset = UTC+1;
                break;
            case "Los Angeles":
                offset = UTC-7;
                break;
            case "Dubai":
                offset= UTC+4;
                break;
            case "Paris":
                offset = UTC+2;
                break;
            case "Moscow":
                offset = UTC+3;
                break;
            case "Cairo":
                offset = UTC+2;
                break;
            case "Hong Kong":
                offset = UTC+8;
                break;
            case "Beijing":
                offset = UTC+8;
                break;
            case "New Delhi":
                offset= UTC+5;
                break;
            case "Mexico City":
                offset = UTC-5;
                break;
            case "Brasilia":
                offset = UTC-3;
                break;
        }

        //if the offset is in the AM
        if(offset < 12)
        {
            //set am
            offset = offset+12;
        }
        //if the offset is in the PM
        else if(offset > 12)
        {
            //set pm
            offset = offset-12;
        }
        else
           //its twelve o'clock
            offset = 12;

        return offset;
    }
公共时间(字符串城市)
{
//采用UTC时间并加/减偏移的结果
整数偏移=0;
//获取使用GMT标准的日历时间实例,然后获取一天中的小时数
Calendar c=Calendar.getInstance(TimeZone.getTimeZone(“GMT”));
int UTC=c.get(日历小时/天);
//根据城市设置偏移量
交换机(城市)
{
案例“纽约”:
偏移量=UTC-4;
打破
“伦敦”案:
偏移量=UTC+1;
打破
“洛杉矶”案:
偏移量=UTC-7;
打破
“迪拜”案:
偏移量=UTC+4;
打破
“巴黎”案:
偏移量=UTC+2;
打破
“莫斯科”案:
偏移量=UTC+3;
打破
“开罗”案:
偏移量=UTC+2;
打破
案例“香港”:
偏移量=UTC+8;
打破
案例“北京”:
偏移量=UTC+8;
打破
案例“新德里”:
偏移量=UTC+5;
打破
“墨西哥城”案:
偏移量=UTC-5;
打破
“巴西利亚”案:
偏移量=UTC-3;
打破
}
//如果偏移量在AM中
如果(偏移量<12)
{
//设置am
偏移量=偏移量+12;
}
//如果偏移量在PM中
否则,如果(偏移量>12)
{
//设定下午
偏移量=偏移量-12;
}
其他的
//十二点了
偏移量=12;
返回偏移量;
}
下面是它在应用程序中的显示方式,用于可视化:

编辑:对不起,我也应该加上这个。因此偏移量返回“转换因子”,我在微调器的onItemSelected事件中使用了该因子。因此,当用户从微调器中选择一个项目时,此函数将读取条目,并根据偏移值设置时间(即小时和分钟,但这也是静态设置的,因为它将始终返回正确的分钟):

@覆盖
已选择公共视图(AdapterView父视图、视图视图、整型位置、长id)
{
如果(convertSpinner.getSelectedItemPosition()==0)
{
//显示当前/本地时间
int hour=c.get(日历小时);
convertTime.setHour(小时);
//currentTime.setHour(小时);
}
else if(convertSpinner.getSelectedItemPosition()==1)
convertTime.setHour(转换工厂(“纽约”);
else if(convertSpinner.getSelectedItemPosition()==2)
convertTime.setHour(转换工厂(“伦敦”);
else if(convertSpinner.getSelectedItemPosition()==3)
convertTime.setHour(转换工厂(“洛杉矶”);
//…其他城市也有同样的流程,因为明显的原因缩短了流程
其他的
转换时间。设定小时(12);
//设定时间
int minute=c.get(Calendar.minute);
convertTime.setMinute(分钟);
}
这也是我的主要观点:

private TimePicker currentTime, convertTime;
private Spinner convertSpinner;

    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState)
    {
        View v= inflater.inflate(R.layout.fragment_time, container, false);
        convertTime = v.findViewById(R.id.convert_clock);
        convertSpinner = v.findViewById(R.id.convert_spinner);

        convertTime.setIs24HourView(false);
        convertTime.setClickable(false);

        //for convert spinner
        ArrayAdapter<CharSequence> adapter2 = ArrayAdapter.createFromResource(getActivity(),R.array.time_cities, android.R.layout.simple_spinner_item);
        adapter2.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        convertSpinner.setAdapter(adapter2);
        convertSpinner.setOnItemSelectedListener(this);

        return v;
}
专用时间选择器currentTime,convertTime;
私人纺纱机;
@凌驾
创建视图时的公共视图(@NonNull LayoutInflater inflater、@Nullable ViewGroup container、@Nullable Bundle savedInstanceState)
{
视图v=充气机。充气(R.layout.fragment\u时间,容器,错误);
convertTime=v.findViewById(R.id.convert\u时钟);
convertSpinner=v.findViewById(R.id.convert\u微调器);
convertTime.setIs24HourView(false);
convertTime.setClickable(假);
//用于转换微调器
ArrayAdapter adapter2=ArrayAdapter.createFromResource(getActivity(),R.array.time\u cities,android.R.layout.simple\u微调器\u项);
adapter2.setDropDownViewResource(android.R.layout.simple\u微调器\u下拉菜单\u项);
convertSpinner.setAdapter(适配器2);
convertSpinner.setOnItemSelectedListener(此);
返回v;
}
java.time 考虑在您的时间工作中使用java.time,即现代java日期和时间API。尤其是当它和你的一样不平凡的时候

要获取洛杉矶的当前时间,请执行以下操作:

    LocalTime timeInLa = LocalTime.now(ZoneId.of("America/Los_Angeles"));
    System.out.println("Current time in LA: " + timeInLa);
刚才运行时的输出:

洛杉矶当前时间:11:10:18.975

对于其他城市,请提供相应的时区ID,例如
欧洲/伦敦
亚洲/迪拜
。巴西利亚的身份证是<
    LocalTime timeInLa = LocalTime.now(ZoneId.of("America/Los_Angeles"));
    System.out.println("Current time in LA: " + timeInLa);
    int hourOfDayInLa = timeInLa.getHour();
    System.out.println("Hour of day in LA: " + hourOfDayInLa);
    int clockHourOfAmOrPm = timeInLa.get(ChronoField.CLOCK_HOUR_OF_AMPM);
    int amOrPmIndexInLa = timeInLa.get(ChronoField.AMPM_OF_DAY);
    String amPm = amOrPmIndexInLa == 0 ? "AM" : "PM";
    System.out.format("Clock hour %d (1 through 12) %s (code %d)%n",
            clockHourOfAmOrPm, amPm, amOrPmIndexInLa);
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;

public class Main {
    public static void main(String... args) {
        // Test
        System.out.println(getOffset("Europe/London"));
        System.out.println(getOffset("Africa/Johannesburg"));
        System.out.println(getOffset("America/Chicago"));
        System.out.println(getOffset("Asia/Calcutta"));
    }

    public static ZoneOffset getOffset(String zoneId) {
        return ZonedDateTime.now(ZoneId.of(zoneId)).getOffset();
    }
}
Z
+02:00
-06:00
+05:30
import java.util.TimeZone;

public class Main {
    public static void main(String... args) {
        // Test
        System.out.println(getOffset("Europe/London"));
        System.out.println(getOffset("Africa/Johannesburg"));
        System.out.println(getOffset("America/Chicago"));
        System.out.println(getOffset("Asia/Calcutta"));
    }

    public static String getOffset(String zoneId) {
        int offset = TimeZone.getTimeZone(zoneId).getRawOffset();// milliseconds to be added to UTC
        int seconds = offset / 1000;
        int hours = seconds / 3600;
        int minutes = (seconds % 3600) / 60;
        return "GMT" + (offset >= 0 ? "+" : "-") + String.format("%02d", Math.abs(hours)) + ":"
                + String.format("%02d", minutes);
    }
}
GMT+00:00
GMT+02:00
GMT-06:00
GMT+05:30
import java.time.ZoneId;
import java.time.ZonedDateTime;

public class Main {
    public static void main(String... args) {
        // Test
        ZonedDateTime zdt = ZonedDateTime.now(ZoneId.systemDefault());
        System.out.println(zdt);
        System.out.println(getZonedDateTimeWithZoneId(zdt, "Europe/London"));
        System.out.println(getZonedDateTimeWithZoneId(zdt, "Africa/Johannesburg"));
        System.out.println(getZonedDateTimeWithZoneId(zdt, "America/Chicago"));
        System.out.println(getZonedDateTimeWithZoneId(zdt, "Asia/Calcutta"));
    }

    public static ZonedDateTime getZonedDateTimeWithZoneId(ZonedDateTime zdt, String zoneId) {
        return zdt.withZoneSameInstant(ZoneId.of(zoneId));
    }
}
2020-12-28T20:03:54.093476Z[Europe/London]
2020-12-28T20:03:54.093476Z[Europe/London]
2020-12-28T22:03:54.093476+02:00[Africa/Johannesburg]
2020-12-28T14:03:54.093476-06:00[America/Chicago]
2020-12-29T01:33:54.093476+05:30[Asia/Calcutta]
import java.time.OffsetDateTime;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;

public class Main {
    public static void main(String... args) {
        // Test
        OffsetDateTime odt = OffsetDateTime.now(ZoneId.systemDefault());
        System.out.println(odt);
        System.out.println(getOffsetDateTimeWithZoneId(odt, "Europe/London"));
        System.out.println(getOffsetDateTimeWithZoneId(odt, "Africa/Johannesburg"));
        System.out.println(getOffsetDateTimeWithZoneId(odt, "America/Chicago"));
        System.out.println(getOffsetDateTimeWithZoneId(odt, "Asia/Calcutta"));
    }

    public static OffsetDateTime getOffsetDateTimeWithZoneId(OffsetDateTime odt, String zoneId) {
        return odt.withOffsetSameInstant(getOffset(zoneId));
    }

    public static ZoneOffset getOffset(String zoneId) {
        return ZonedDateTime.now(ZoneId.of(zoneId)).getOffset();
    }
}
2020-12-28T20:08:25.026349Z
2020-12-28T20:08:25.026349Z
2020-12-28T22:08:25.026349+02:00
2020-12-28T14:08:25.026349-06:00
2020-12-29T01:38:25.026349+05:30
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;
import java.util.TimeZone;

public class Main {
    public static void main(String... args) throws ParseException {
        // Test
        Date date = Calendar.getInstance().getTime();
        System.out.println(date);
        System.out.println(getFormattedDateTimeWithZoneId(date, "Europe/London"));
        System.out.println(getFormattedTimeWithZoneId(date, "Europe/London"));
        System.out.println(getFormattedDateTimeWithZoneId(date, "Africa/Johannesburg"));
        System.out.println(getFormattedTimeWithZoneId(date, "Africa/Johannesburg"));
        System.out.println(getFormattedDateTimeWithZoneId(date, "America/Chicago"));
        System.out.println(getFormattedTimeWithZoneId(date, "America/Chicago"));
        System.out.println(getFormattedDateTimeWithZoneId(date, "Asia/Calcutta"));
        System.out.println(getFormattedTimeWithZoneId(date, "Asia/Calcutta"));
    }

    public static String getFormattedDateTimeWithZoneId(Date date, String zoneId) throws ParseException {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss a zzz", Locale.ENGLISH);
        sdf.setTimeZone(TimeZone.getTimeZone(getOffset(zoneId)));
        return sdf.format(date);
    }

    public static String getFormattedTimeWithZoneId(Date date, String zoneId) throws ParseException {
        SimpleDateFormat sdf = new SimpleDateFormat("hh:mm:ss a", Locale.ENGLISH);
        sdf.setTimeZone(TimeZone.getTimeZone(getOffset(zoneId)));
        return sdf.format(date);
    }

    public static String getOffset(String zoneId) {
        int offset = TimeZone.getTimeZone(zoneId).getRawOffset();// milliseconds to be added to UTC
        int seconds = offset / 1000;
        int hours = seconds / 3600;
        int minutes = (seconds % 3600) / 60;
        return "GMT" + (offset >= 0 ? "+" : "-") + String.format("%02d", Math.abs(hours)) + ":"
                + String.format("%02d", minutes);
    }
}
Mon Dec 28 20:47:25 GMT 2020
2020-12-28 08:47:25 PM GMT+00:00
08:47:25 PM
2020-12-28 10:47:25 PM GMT+02:00
10:47:25 PM
2020-12-28 02:47:25 PM GMT-06:00
02:47:25 PM
2020-12-29 02:17:25 AM GMT+05:30
02:17:25 AM