如何转换不同时区的时间

how to convert time for different timezones

所以我正在制作一个消息传递应用程序,但我无法正确完成代码

这是发送按钮:

sendbutton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View _view) {
                if (img == 0) {
                    if (edittext1.getText().toString().equals("")) {
                        
                    }
                    else {
                        Numberrr++;
                        mm = new HashMap<>();
                        mm.put("username", get_name);
                        mm.put("pfp", get_pfp);
                        mm.put("messages", edittext1.getText().toString().trim());
                        mm.put("user_uid", FirebaseAuth.getInstance().getCurrentUser().getUid());
                        mm.put("number", String.valueOf((long)(Numberrr)));
                        cal = Calendar.getInstance();
                        mm.put("time", new SimpleDateFormat("E hh:mm s").format(cal.getTime()));
                        ch.push().updateChildren(mm);
                        mm.clear();
                        edittext1.setText("");
                        lastText.edit().putString("Lasttext", String.valueOf((long)(Numberrr))).commit();
                    }
                }
                else {
                    store.child(imgName).putFile(Uri.fromFile(new File(imgPath))).addOnFailureListener(_store_failure_listener).addOnProgressListener(_store_upload_progress_listener).continueWithTask(new Continuation<UploadTask.TaskSnapshot, Task<Uri>>() {
                        @Override
                        public Task<Uri> then(Task<UploadTask.TaskSnapshot> task) throws Exception {
                            return store.child(imgName).getDownloadUrl();
                        }
                    }).addOnCompleteListener(_store_upload_success_listener);
                    progressbar1.setVisibility(View.VISIBLE);
                    sendbutton.setEnabled(false);
                    edittext1.setEnabled(false);
                }
            }
        });

这是 ListView 代码的一部分:

            LayoutInflater _inflater = (LayoutInflater) getBaseContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            View _view = _v;
            if (_view == null) {
                _view = _inflater.inflate(R.layout.messgebubble, null);
            }

            final LinearLayout time = _view.findViewById(R.id.time);
            final TextView textview1 = _view.findViewById(R.id.textview1);
            final LinearLayout linear4 = _view.findViewById(R.id.linear4);
            final TextView timetext = _view.findViewById(R.id.timetext);
            final LinearLayout left = _view.findViewById(R.id.left);
            final LinearLayout linear1 = _view.findViewById(R.id.linear1);
            final de.hdodenhof.circleimageview.CircleImageView circleimageview1 = _view.findViewById(R.id.circleimageview1);
            final TextView message = _view.findViewById(R.id.message);
            final ImageView imageview1 = _view.findViewById(R.id.imageview1);
            final TextView SystemText = _view.findViewById(R.id.systemtext);
            final LinearLayout system = _view.findViewById(R.id.system);
//This is to set the time on text view 
            timetext.setText(new Sim("MM/yyyy hh:mm:ss").format(_data.get((int)_position).get("time").toString()));
//end

所以我正在尝试让消息在不同时区显示正确的消息时间

例如如果有人在 (UTC+1) 但消息来自 (UTC+5) 并且消息是在 17:35(UTC+5) 发送的,它会显示 17:35 但它应该显示 14:35...如您所知,这也会在代码中引起很多问题。

编辑:修订

你的问题不清楚。但这些要点可能会对您有所帮助:

  • 永远不要使用遗留的 date-time classes,例如 DateCalendarSimpleDateFormat 等。它们 很糟糕。仅使用 JSR 310.
  • 中定义的现代 java.time classes
  • 要跟踪时刻,时间线上的特定点,请使用 java.time.Instant class“以 UTC”(与 UTC 的偏移量为零 hours-minutes-seconds)执行此操作。
  • 要以文本方式序列化时刻以进行数据存储或数据交换,请使用标准 ISO 8601 格式。通常最好在 UTC 中这样做,使用 Instant#toStringInstant.parse.

这是一些简短的代码。但搜索以了解更多信息。所有这些都已在 Stack Overflow 上多次提及。

捕捉当下瞬间

使用 java.time.Instant 表示 UTC 中的时刻。

Instant instant = Instant.now() ;  // Capture the current moment as seen in UTC. 
String s = instant.toString() ;    // Generate text in standard ISO 8601 format. 

解析

这里我们解析标准 ISO 8601 格式的文本。

Instant instant = Instant.parse( "2022-04-19T15:30:14.348767Z" ) ;

调整到时区

为了向用户展示,您可能需要调整到特定时区。同一时刻,时间轴上的同一点,不同的 wall-clock 时间。

ZoneId z = ZoneId.of( "America/Edmonton" ) ;
ZonedDateTime zdt = instant.atZone( z ) ;

生成文本

标准格式

要生成标准格式的文本,只需调用 toString

instant.toString(): 2022-04-19T15:30:14.348767Z

zdt.toString(): 2022-04-19T09:30:14.348767-06:00[America/Edmonton]

实际上最后一个是标准格式的明智扩展,将时区名称附加在方括号中。

本地化格式

要生成本地化格式的文本,请使用 DateTimeFormatter.ofLocalizedDateTime

FormatStyle style = FormatStyle.SHORT ;
Locale locale = Locale.CANADA_FRENCH ;  // Or Locale.US or new Locale( "fr" , "MA" ) (French in Morocco), etc.
DateTimeFormatter f = DateTimeFormatter.ofLocalizedDateTime( style ).withLocale( locale ) ;
String output = zdt.format( f );

看到这个code run live at IdeOne.com

output: 22-04-19 09 h 30

您当然可以通过 DateTimeFormatter.ofPattern 指定自定义格式。 (Search 以了解更多信息。)但自动本地化可能会让您的生活更简单。